Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / detection_output_test.cpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 #include <gtest/gtest.h>
19 #include "api/CPP/memory.hpp"
20 #include <api/CPP/input_layout.hpp>
21 #include "api/CPP/detection_output.hpp"
22 #include <api/CPP/topology.hpp>
23 #include <api/CPP/network.hpp>
24 #include <api/CPP/engine.hpp>
25 #include "test_utils/test_utils.h"
26
27 namespace cldnn
28 {
29     template<> struct type_to_data_type<FLOAT16> { static const data_types value = data_types::f16; };
30 }
31
32 using namespace cldnn;
33 using namespace tests;
34
35 template <typename T>
36 class detection_output_test : public ::testing::Test
37 {
38
39 public:
40     detection_output_test() :
41         nms_threshold(0.1f)
42     {}
43
44     void init_buffers(cldnn::memory prior_memory, cldnn::memory confidence_memory, cldnn::memory location_memory,
45                       bool share_location, bool variance_encoded_in_target = false,
46                       int prior_info_size = 4, int prior_coordinates_offset = 0, bool prior_is_normalized = true)
47     {
48         auto location_ptr = location_memory.pointer<T>();
49         auto confidence_ptr = confidence_memory.pointer<T>();
50         auto prior_box_ptr = prior_memory.pointer<T>();
51
52         T* prior_data = prior_box_ptr.data();
53         T* confidence_data = confidence_ptr.data();
54         T* location_data = location_ptr.data();
55
56         // Fill prior-box data.
57         const float step = 0.5f;
58         const float box_size = 0.3f;
59         const float prior_multiplier = prior_is_normalized ? 1.0f : static_cast<float>(this->img_size);
60         const float variance = 0.1f;
61         int idx = 0;
62         for (int h = 0; h < 2; ++h)
63         {
64             float center_y = (h + 0.5f) * step;
65             for (int w = 0; w < 2; ++w) 
66             {
67                 float center_x = (w + 0.5f) * step;
68                 prior_data[idx+prior_coordinates_offset+0] = (center_x - box_size / 2) * prior_multiplier;
69                 prior_data[idx+prior_coordinates_offset+1] = (center_y - box_size / 2) * prior_multiplier;
70                 prior_data[idx+prior_coordinates_offset+2] = (center_x + box_size / 2) * prior_multiplier;
71                 prior_data[idx+prior_coordinates_offset+3] = (center_y + box_size / 2) * prior_multiplier;
72
73                 idx += prior_info_size;
74             }
75         }
76         if (!variance_encoded_in_target)
77         {
78             for (int i = 0; i < idx; ++i)
79             {
80                 prior_data[idx + i] = variance;
81             }
82         }
83
84         // Fill confidences.
85         idx = 0;
86         for (int i = 0; i < num_of_images; ++i) 
87         {
88             for (int j = 0; j < num_priors; ++j) 
89             {
90                 for (int c = 0; c < num_classes; ++c) 
91                 {
92                     if (i % 2 == c % 2) 
93                     {
94                         confidence_data[idx++] = j * 0.2f;
95                     }
96                     else 
97                     {
98                         confidence_data[idx++] = 1 - j * 0.2f;
99                     }
100                 }
101             }
102         }
103
104         // Fill locations.
105         const int num_loc_classes = share_location ? 1 : num_classes;
106         const float loc_multiplier = variance_encoded_in_target ? variance : 1.0f;
107         idx = 0;
108         for (int i = 0; i < num_of_images; ++i) 
109         {
110             for (int h = 0; h < 2; ++h) 
111             {
112                 for (int w = 0; w < 2; ++w) 
113                 {
114                     for (int c = 0; c < num_loc_classes; ++c) 
115                     {
116                         location_data[idx++] = (w % 2 ? -1 : 1) * (i * 1 + c / 2.f + 0.5f) * loc_multiplier;
117                         location_data[idx++] = (h % 2 ? -1 : 1) * (i * 1 + c / 2.f + 0.5f) * loc_multiplier;
118                         location_data[idx++] = (w % 2 ? -1 : 1) * (i * 1 + c / 2.f + 0.5f) * loc_multiplier;
119                         location_data[idx++] = (h % 2 ? -1 : 1) * (i * 1 + c / 2.f + 0.5f) * loc_multiplier;
120                     }
121                 }
122             }
123         }
124     }
125
126     void init_buffer_sort(cldnn::memory input_buff)
127     {
128         auto input_data_ptr = input_buff.pointer<T>();
129
130         EXPECT_EQ((int)input_buff.count(), 128);
131
132         T* input_data = input_data_ptr.data();
133         input_data[0] = 8;
134         input_data[1] = 3;
135         input_data[16] = 0; input_data[17] = 0; input_data[18] = 0.6f; input_data[19] = 0.55f; input_data[20] = 0.55f; input_data[21] = 0.85f; input_data[22] = 0.85f;
136         input_data[23] = 0; input_data[24] = 0; input_data[25] = 0.4f; input_data[26] = 0.15f; input_data[27] = 0.55f; input_data[28] = 0.45f; input_data[29] = 0.85f;
137         input_data[30] = 0; input_data[31] = 0; input_data[32] = 0.2f; input_data[33] = 0.55f; input_data[34] = 0.15f; input_data[35] = 0.85f; input_data[36] = 0.45f;
138         input_data[37] = 0; input_data[38] = 0; input_data[39] = 0.0f; input_data[40] = 0.15f; input_data[41] = 0.15f; input_data[42] = 0.45f; input_data[43] = 0.45f;
139         input_data[44] = 0; input_data[45] = 1; input_data[46] = 1.0f; input_data[47] = 0.20f; input_data[48] = 0.20f; input_data[49] = 0.50f; input_data[50] = 0.50f;
140         input_data[51] = 0; input_data[52] = 1; input_data[53] = 0.8f; input_data[54] = 0.50f; input_data[55] = 0.20f; input_data[56] = 0.80f; input_data[57] = 0.50f;
141         input_data[58] = 0; input_data[59] = 1; input_data[60] = 0.6f; input_data[61] = 0.20f; input_data[62] = 0.50f; input_data[63] = 0.50f; input_data[64] = 0.80f;
142         input_data[65] = 0; input_data[66] = 1; input_data[67] = 0.4f; input_data[68] = 0.50f; input_data[69] = 0.50f; input_data[70] = 0.80f; input_data[71] = 0.80f;
143         input_data[72] = 1; input_data[73] = 0; input_data[74] = 1.0f; input_data[75] = 0.25f; input_data[76] = 0.25f; input_data[77] = 0.55f; input_data[78] = 0.55f;
144         input_data[79] = 1; input_data[80] = 0; input_data[81] = 0.4f; input_data[82] = 0.45f; input_data[83] = 0.45f; input_data[84] = 0.75f; input_data[85] = 0.75f;
145         input_data[86] = -1; input_data[87] = 0; input_data[88] = 0; input_data[89] = 0; input_data[90] = 0; input_data[91] = 0; input_data[92] = 0;
146         input_data[93] = -1; input_data[94] = 0; input_data[95] = 0; input_data[96] = 0; input_data[97] = 0; input_data[98] = 0; input_data[99] = 0;
147         input_data[100] = 1; input_data[101] = 1; input_data[102] = 0.6f; input_data[103] = 0.40f; input_data[104] = 0.40f; input_data[105] = 0.70f; input_data[106] = 0.70f;
148         input_data[107] = -1; input_data[108] = 0; input_data[109] = 0; input_data[110] = 0; input_data[111] = 0; input_data[112] = 0; input_data[113] = 0;
149         input_data[114] = -1; input_data[115] = 0; input_data[116] = 0; input_data[117] = 0; input_data[118] = 0; input_data[119] = 0; input_data[120] = 0;
150         input_data[121] = -1; input_data[122] = 0; input_data[123] = 0; input_data[124] = 0; input_data[125] = 0; input_data[126] = 0; input_data[127] = 0;
151     }
152
153     void check_results(const memory& output, const int num, const std::string values)
154     {
155         assert(num < output.get_layout().size.spatial[1]);
156
157         // Split values to vector of items.
158         std::vector<std::string> items;
159         std::istringstream iss(values);
160         std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), back_inserter(items));
161         EXPECT_EQ((int)items.size(), 7);
162
163         // Check data.
164         auto out_ptr = output.pointer<T>();
165         const T* data = out_ptr.data();
166         for (int i = 0; i < 2; ++i)
167         {
168             EXPECT_EQ(static_cast<int>((float)data[num * output.get_layout().size.spatial[0] + i]), atoi(items[i].c_str()));
169         }
170         for (int i = 2; i < 7; ++i) 
171         {
172             EXPECT_TRUE(floating_point_equal(data[num * output.get_layout().size.spatial[0] + i], (T)(float)atof(items[i].c_str())));
173         }
174     }
175
176     void setup_basic(bool runOnGPU)
177     {
178         const bool share_location = true;
179         const int num_loc_classes = share_location ? 1 : this->num_classes;
180         const int keep_top_k = 150;
181
182         const auto& engine = get_test_engine();
183         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
184         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
185         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
186
187         topology topology;
188         topology.add(input_layout("input_location", input_location.get_layout()));
189         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
190         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
191
192         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k));
193
194         build_options opts;
195         if (runOnGPU)
196         {
197             opts.set_option(build_option::detection_output_gpu(true));
198         }
199
200         network network(engine, topology, opts);
201         network.set_input_data("input_location", input_location);
202         network.set_input_data("input_confidence", input_confidence);
203         network.set_input_data("input_prior_box", input_prior_box);
204
205         auto outputs = network.execute();
206
207         EXPECT_EQ(outputs.size(), size_t(1));
208         EXPECT_EQ(outputs.begin()->first, "detection_output");
209
210         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
211         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
212         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
213         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
214     }
215
216     void setup_two_layers(bool runOnGPU)
217     {
218         const bool share_location = true;
219         const int num_loc_classes = share_location ? 1 : this->num_classes;
220         const int keep_top_k = 150;
221
222         const auto& engine = get_test_engine();
223         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
224         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
225         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
226
227         topology topology;
228         topology.add(input_layout("input_location", input_location.get_layout()));
229         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
230         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
231
232         topology.add(detection_output("detection_output_1", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k));
233         topology.add(detection_output("detection_output_2", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k));
234
235         build_options opts;
236         if (runOnGPU)
237         {
238             opts.set_option(build_option::detection_output_gpu(true));
239         }
240
241         network network(engine, topology, opts);
242         network.set_input_data("input_location", input_location);
243         network.set_input_data("input_confidence", input_confidence);
244         network.set_input_data("input_prior_box", input_prior_box);
245
246         auto outputs = network.execute();
247
248         EXPECT_EQ(outputs.size(), size_t(2));
249         unsigned i = 1;
250         for (auto it = outputs.begin(); it != outputs.begin(); it++)
251         {
252
253             EXPECT_EQ(it->first, "detection_output_" + std::to_string(i));
254
255             EXPECT_EQ(it->second.get_memory().get_layout().size.batch[0], 1);
256             EXPECT_EQ(it->second.get_memory().get_layout().size.feature[0], 1);
257             EXPECT_EQ(it->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
258             EXPECT_EQ(it->second.get_memory().get_layout().size.spatial[0], 7);
259             i++;
260         }
261     }
262
263     void forward_share_location(bool runOnGPU)
264     {
265         const bool share_location = true;
266         const int num_loc_classes = share_location ? 1 : this->num_classes;
267         const int keep_top_k = 4;
268         const int background_label_id = 0;
269
270         const auto& engine = get_test_engine();
271         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
272         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
273         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
274
275         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
276
277         topology topology;
278         topology.add(input_layout("input_location", input_location.get_layout()));
279         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
280         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
281
282         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold));
283
284         build_options opts;
285         if (runOnGPU)
286         {
287             opts.set_option(build_option::detection_output_gpu(true));
288         }
289
290         network network(engine, topology, opts);
291         network.set_input_data("input_location", input_location);
292         network.set_input_data("input_confidence", input_confidence);
293         network.set_input_data("input_prior_box", input_prior_box);
294
295         auto outputs = network.execute();
296
297         EXPECT_EQ(outputs.size(), size_t(1));
298         EXPECT_EQ(outputs.begin()->first, "detection_output");
299
300         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
301         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
302         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
303         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
304
305         auto output_prim = outputs.begin()->second.get_memory();
306
307         check_results(output_prim, 0, "0 1 1.0 0.15 0.15 0.45 0.45");
308         check_results(output_prim, 1, "0 1 0.8 0.55 0.15 0.85 0.45");
309         check_results(output_prim, 2, "0 1 0.6 0.15 0.55 0.45 0.85");
310         check_results(output_prim, 3, "0 1 0.4 0.55 0.55 0.85 0.85");
311         check_results(output_prim, 4, "1 1 0.6 0.45 0.45 0.75 0.75");
312         check_results(output_prim, 5, "1 1 0.0 0.25 0.25 0.55 0.55");
313         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
314         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
315     }
316
317     void forward_num_detections_greater_than_keep_top_k(bool runOnGPU)
318     {
319         const bool share_location = true;
320         const int num_loc_classes = share_location ? 1 : this->num_classes;
321         const int keep_top_k = 1;
322         const int background_label_id = 0;
323
324         const auto& engine = get_test_engine();
325         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
326         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
327         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
328
329         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
330
331         topology topology;
332         topology.add(input_layout("input_location", input_location.get_layout()));
333         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
334         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
335
336         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold));
337
338         build_options opts;
339         if (runOnGPU)
340         {
341             opts.set_option(build_option::detection_output_gpu(true));
342         }
343
344         network network(engine, topology, opts);
345         network.set_input_data("input_location", input_location);
346         network.set_input_data("input_confidence", input_confidence);
347         network.set_input_data("input_prior_box", input_prior_box);
348
349         auto outputs = network.execute();
350
351         EXPECT_EQ(outputs.size(), size_t(1));
352         EXPECT_EQ(outputs.begin()->first, "detection_output");
353
354         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
355         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
356         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
357         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
358
359         auto output_prim = outputs.begin()->second.get_memory();
360
361         check_results(output_prim, 0, "0 1 1.0 0.15 0.15 0.45 0.45");
362         check_results(output_prim, 1, "1 1 0.6 0.45 0.45 0.75 0.75");
363     }
364
365     void forward_num_detections_smaller_than_keep_top_k(bool runOnGPU)
366     {
367         const bool share_location = true;
368         const int num_loc_classes = share_location ? 1 : this->num_classes;
369         const int keep_top_k = 6;
370         const int background_label_id = 0;
371
372         const auto& engine = get_test_engine();
373         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
374         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
375         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
376
377         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
378
379         topology topology;
380         topology.add(input_layout("input_location", input_location.get_layout()));
381         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
382         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
383
384         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold));
385
386         build_options opts;
387         if (runOnGPU)
388         {
389             opts.set_option(build_option::detection_output_gpu(true));
390         }
391
392         network network(engine, topology, opts);
393         network.set_input_data("input_location", input_location);
394         network.set_input_data("input_confidence", input_confidence);
395         network.set_input_data("input_prior_box", input_prior_box);
396
397         auto outputs = network.execute();
398
399         EXPECT_EQ(outputs.size(), size_t(1));
400         EXPECT_EQ(outputs.begin()->first, "detection_output");
401
402         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
403         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
404         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
405         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
406
407         auto output_prim = outputs.begin()->second.get_memory();
408
409         check_results(output_prim, 0, "0 1 1.0 0.15 0.15 0.45 0.45");
410         check_results(output_prim, 1, "0 1 0.8 0.55 0.15 0.85 0.45");
411         check_results(output_prim, 2, "0 1 0.6 0.15 0.55 0.45 0.85");
412         check_results(output_prim, 3, "0 1 0.4 0.55 0.55 0.85 0.85");
413         check_results(output_prim, 4, "1 1 0.6 0.45 0.45 0.75 0.75");
414         check_results(output_prim, 5, "1 1 0.0 0.25 0.25 0.55 0.55");
415         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
416         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
417         check_results(output_prim, 8, "-1 0 0 0 0 0 0");
418         check_results(output_prim, 9, "-1 0 0 0 0 0 0");
419         check_results(output_prim, 10, "-1 0 0 0 0 0 0");
420         check_results(output_prim, 11, "-1 0 0 0 0 0 0");
421     }
422
423     void test_forward_share_location_top_k(bool runOnGPU)
424     {
425         const bool share_location = true;
426         const int num_loc_classes = share_location ? 1 : this->num_classes;
427         const int keep_top_k = 2;
428         const int top_k = 2;
429         const int background_label_id = 0;
430
431         const auto& engine = get_test_engine();
432         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
433         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
434         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
435
436         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
437
438         topology topology;
439         topology.add(input_layout("input_location", input_location.get_layout()));
440         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
441         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
442
443         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold, top_k));
444
445         build_options opts;
446         if (runOnGPU)
447         {
448             opts.set_option(build_option::detection_output_gpu(true));
449         }
450
451         network network(engine, topology, opts);
452         network.set_input_data("input_location", input_location);
453         network.set_input_data("input_confidence", input_confidence);
454         network.set_input_data("input_prior_box", input_prior_box);
455
456         auto outputs = network.execute();
457
458         EXPECT_EQ(outputs.size(), size_t(1));
459         EXPECT_EQ(outputs.begin()->first, "detection_output");
460
461         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
462         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
463         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
464         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
465
466         auto output_prim = outputs.begin()->second.get_memory();
467
468         check_results(output_prim, 0, "0 1 1.0 0.15 0.15 0.45 0.45");
469         check_results(output_prim, 1, "0 1 0.8 0.55 0.15 0.85 0.45");
470         check_results(output_prim, 2, "1 1 0.6 0.45 0.45 0.75 0.75");
471         check_results(output_prim, 3, "-1 0 0 0 0 0 0");
472     }
473
474     void forward_no_share_location(bool runOnGPU)
475     {
476         const bool share_location = false;
477         const int num_loc_classes = share_location ? 1 : this->num_classes;
478         const int keep_top_k = 10;
479         const int background_label_id = -1;
480
481         const auto& engine = get_test_engine();
482         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
483         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
484         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
485
486         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
487
488         topology topology;
489         topology.add(input_layout("input_location", input_location.get_layout()));
490         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
491         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
492
493         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold));
494
495         build_options opts;
496         if (runOnGPU)
497         {
498             opts.set_option(build_option::detection_output_gpu(true));
499         }
500
501         network network(engine, topology, opts);
502         network.set_input_data("input_location", input_location);
503         network.set_input_data("input_confidence", input_confidence);
504         network.set_input_data("input_prior_box", input_prior_box);
505
506         auto outputs = network.execute();
507
508         EXPECT_EQ(outputs.size(), size_t(1));
509         EXPECT_EQ(outputs.begin()->first, "detection_output");
510
511         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
512         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
513         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
514         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
515
516         auto output_prim = outputs.begin()->second.get_memory();
517
518         check_results(output_prim, 0, "0 0 0.6 0.55 0.55 0.85 0.85");
519         check_results(output_prim, 1, "0 0 0.4 0.15 0.55 0.45 0.85");
520         check_results(output_prim, 2, "0 0 0.2 0.55 0.15 0.85 0.45");
521         check_results(output_prim, 3, "0 0 0.0 0.15 0.15 0.45 0.45");
522         check_results(output_prim, 4, "0 1 1.0 0.20 0.20 0.50 0.50");
523         check_results(output_prim, 5, "0 1 0.8 0.50 0.20 0.80 0.50");
524         check_results(output_prim, 6, "0 1 0.6 0.20 0.50 0.50 0.80");
525         check_results(output_prim, 7, "0 1 0.4 0.50 0.50 0.80 0.80");
526         check_results(output_prim, 8, "1 0 1.0 0.25 0.25 0.55 0.55");
527         check_results(output_prim, 9, "1 0 0.4 0.45 0.45 0.75 0.75");
528         check_results(output_prim, 10, "1 1 0.6 0.40 0.40 0.70 0.70");
529         check_results(output_prim, 11, "-1 0 0 0 0 0 0");
530         check_results(output_prim, 12, "-1 0 0 0 0 0 0");
531         check_results(output_prim, 13, "-1 0 0 0 0 0 0");
532         check_results(output_prim, 14, "-1 0 0 0 0 0 0");
533         check_results(output_prim, 15, "-1 0 0 0 0 0 0");
534         check_results(output_prim, 16, "-1 0 0 0 0 0 0");
535         check_results(output_prim, 17, "-1 0 0 0 0 0 0");
536         check_results(output_prim, 18, "-1 0 0 0 0 0 0");
537         check_results(output_prim, 19, "-1 0 0 0 0 0 0");
538     }
539
540     void forward_no_share_location_top_k(bool runOnGPU)
541     {
542         const bool share_location = false;
543         const int num_loc_classes = share_location ? 1 : this->num_classes;
544         const int keep_top_k = 4;
545         const int background_label_id = -1;
546         const int top_k = 2;
547
548         const auto& engine = get_test_engine();
549         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
550         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
551         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
552
553         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
554
555         topology topology;
556         topology.add(input_layout("input_location", input_location.get_layout()));
557         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
558         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
559
560         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold, top_k));
561
562         build_options opts;
563         if (runOnGPU)
564         {
565             opts.set_option(build_option::detection_output_gpu(true));
566         }
567
568         network network(engine, topology, opts);
569         network.set_input_data("input_location", input_location);
570         network.set_input_data("input_confidence", input_confidence);
571         network.set_input_data("input_prior_box", input_prior_box);
572
573         auto outputs = network.execute();
574
575         EXPECT_EQ(outputs.size(), size_t(1));
576         EXPECT_EQ(outputs.begin()->first, "detection_output");
577
578         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
579         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
580         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
581         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
582
583         auto output_prim = outputs.begin()->second.get_memory();
584
585         check_results(output_prim, 0, "0 0 0.6 0.55 0.55 0.85 0.85");
586         check_results(output_prim, 1, "0 0 0.4 0.15 0.55 0.45 0.85");
587         check_results(output_prim, 2, "0 1 1.0 0.20 0.20 0.50 0.50");
588         check_results(output_prim, 3, "0 1 0.8 0.50 0.20 0.80 0.50");
589         check_results(output_prim, 4, "1 0 1.0 0.25 0.25 0.55 0.55");
590         check_results(output_prim, 5, "1 1 0.6 0.40 0.40 0.70 0.70");
591         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
592         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
593     }
594
595     void forward_no_share_location_neg_0(bool runOnGPU)
596     {
597         const bool share_location = false;
598         const int num_loc_classes = share_location ? 1 : this->num_classes;
599         const int keep_top_k = 5;
600         const int background_label_id = 0;
601
602         const auto& engine = get_test_engine();
603         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
604         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
605         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
606
607         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
608
609         topology topology;
610         topology.add(input_layout("input_location", input_location.get_layout()));
611         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
612         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
613
614         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold));
615
616         build_options opts;
617         if (runOnGPU)
618         {
619             opts.set_option(build_option::detection_output_gpu(true));
620         }
621
622         network network(engine, topology, opts);
623         network.set_input_data("input_location", input_location);
624         network.set_input_data("input_confidence", input_confidence);
625         network.set_input_data("input_prior_box", input_prior_box);
626
627         auto outputs = network.execute();
628
629         EXPECT_EQ(outputs.size(), size_t(1));
630         EXPECT_EQ(outputs.begin()->first, "detection_output");
631
632         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
633         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
634         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
635         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
636
637         auto output_prim = outputs.begin()->second.get_memory();
638
639         check_results(output_prim, 0, "0 1 1.0 0.20 0.20 0.50 0.50");
640         check_results(output_prim, 1, "0 1 0.8 0.50 0.20 0.80 0.50");
641         check_results(output_prim, 2, "0 1 0.6 0.20 0.50 0.50 0.80");
642         check_results(output_prim, 3, "0 1 0.4 0.50 0.50 0.80 0.80");
643         check_results(output_prim, 4, "1 1 0.6 0.40 0.40 0.70 0.70");
644         check_results(output_prim, 5, "-1 0 0 0 0 0 0");
645         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
646         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
647         check_results(output_prim, 8, "-1 0 0 0 0 0 0");
648         check_results(output_prim, 9, "-1 0 0 0 0 0 0");
649     }
650
651     void forward_no_share_location_neg_0_top_k(bool runOnGPU)
652     {
653         const bool share_location = false;
654         const int num_loc_classes = share_location ? 1 : this->num_classes;
655         const int keep_top_k = 2;
656         const int background_label_id = 0;
657         const int top_k = 2;
658
659         const auto& engine = get_test_engine();
660         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
661         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
662         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
663
664         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
665
666         topology topology;
667         topology.add(input_layout("input_location", input_location.get_layout()));
668         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
669         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
670
671         topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold, top_k));
672
673         build_options opts;
674         if (runOnGPU)
675         {
676             opts.set_option(build_option::detection_output_gpu(true));
677         }
678
679         network network(engine, topology, opts);
680         network.set_input_data("input_location", input_location);
681         network.set_input_data("input_confidence", input_confidence);
682         network.set_input_data("input_prior_box", input_prior_box);
683
684         auto outputs = network.execute();
685
686         EXPECT_EQ(outputs.size(), size_t(1));
687         EXPECT_EQ(outputs.begin()->first, "detection_output");
688
689         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
690         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
691         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
692         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
693
694         auto output_prim = outputs.begin()->second.get_memory();
695
696         check_results(output_prim, 0, "0 1 1.0 0.20 0.20 0.50 0.50");
697         check_results(output_prim, 1, "0 1 0.8 0.50 0.20 0.80 0.50");
698         check_results(output_prim, 2, "1 1 0.6 0.40 0.40 0.70 0.70");
699         check_results(output_prim, 3, "-1 0 0 0 0 0 0");
700     }
701
702     void forward_no_share_location_top_k_input_padding(bool runOnGPU)
703     {
704         const bool share_location = false;
705         const int num_loc_classes = share_location ? 1 : this->num_classes;
706         const int keep_top_k = 4;
707         const int background_label_id = -1;
708         const int top_k = 2;
709
710         const auto& engine = get_test_engine();
711         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
712         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
713         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 2, 1, this->num_priors * 4 } });
714
715         this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
716         topology topology;
717         topology.add(input_layout("input_location", input_location.get_layout()));
718         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
719         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
720         topology.add(reorder("input_location_padded", "input_location", input_location.get_layout().with_padding({ { 0, 0, 12, 3 },{ 0, 0, 5, 11 } })));
721         topology.add(reorder("input_confidence_padded", "input_confidence", input_location.get_layout().with_padding({ { 0, 0, 2, 7 },{ 0, 0, 13, 1 } })));
722
723         topology.add(detection_output("detection_output", "input_location_padded", "input_confidence_padded", "input_prior_box", this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold, top_k));
724
725         build_options opts;
726         if (runOnGPU)
727         {
728             opts.set_option(build_option::detection_output_gpu(true));
729         }
730
731         network network(engine, topology, opts);
732         network.set_input_data("input_location", input_location);
733         network.set_input_data("input_confidence", input_confidence);
734         network.set_input_data("input_prior_box", input_prior_box);
735
736         auto outputs = network.execute();
737
738         EXPECT_EQ(outputs.size(), size_t(1));
739         EXPECT_EQ(outputs.begin()->first, "detection_output");
740
741         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
742         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
743         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
744         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
745
746         auto output_prim = outputs.begin()->second.get_memory();
747
748         check_results(output_prim, 0, "0 0 0.6 0.55 0.55 0.85 0.85");
749         check_results(output_prim, 1, "0 0 0.4 0.15 0.55 0.45 0.85");
750         check_results(output_prim, 2, "0 1 1.0 0.20 0.20 0.50 0.50");
751         check_results(output_prim, 3, "0 1 0.8 0.50 0.20 0.80 0.50");
752         check_results(output_prim, 4, "1 0 1.0 0.25 0.25 0.55 0.55");
753         check_results(output_prim, 5, "1 1 0.6 0.40 0.40 0.70 0.70");
754         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
755         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
756     }
757
758     void test_forward_no_share_location_top_k_faster_rcnn_case(bool runOnGPU)
759     {
760         const bool share_location = false;
761         const int num_loc_classes = share_location ? 1 : this->num_classes;
762         const int keep_top_k = 4;
763         const int background_label_id = -1;
764         const int top_k = 2;
765         const float eta = 1.0f;
766         const prior_box_code_type code_type = prior_box_code_type::corner;
767         const bool variance_encoded_in_target = true;
768         const float confidence_threshold = -std::numeric_limits<float>::max();
769         const int32_t prior_info_size = 5;
770         const int32_t prior_coordinates_offset = 1;
771         const bool prior_is_normalized = true;
772
773         const auto& engine = get_test_engine();
774         cldnn::memory input_location = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * num_loc_classes * 4, 1, 1 } });
775         cldnn::memory input_confidence = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ this->num_of_images, this->num_priors * this->num_classes, 1, 1 } });
776         cldnn::memory input_prior_box = memory::allocate(engine, { type_to_data_type<T>::value, format::bfyx,{ 1, 1, 1, this->num_priors * prior_info_size } });
777
778         this->init_buffers(input_prior_box, input_confidence, input_location, share_location, variance_encoded_in_target,
779             prior_info_size, prior_coordinates_offset, prior_is_normalized);
780
781         topology topology;
782         topology.add(input_layout("input_location", input_location.get_layout()));
783         topology.add(input_layout("input_confidence", input_confidence.get_layout()));
784         topology.add(input_layout("input_prior_box", input_prior_box.get_layout()));
785         topology.add(reorder("input_location_padded", "input_location", input_location.get_layout().with_padding({ { 0, 0, 12, 3 },{ 0, 0, 5, 11 } })));
786         topology.add(reorder("input_confidence_padded", "input_confidence", input_location.get_layout().with_padding({ { 0, 0, 2, 7 },{ 0, 0, 13, 1 } })));
787
788         topology.add(detection_output("detection_output", "input_location_padded", "input_confidence_padded", "input_prior_box",
789             this->num_classes, keep_top_k, share_location, background_label_id, this->nms_threshold, top_k,
790             eta, code_type, variance_encoded_in_target, confidence_threshold, prior_info_size, prior_coordinates_offset,
791             prior_is_normalized, this->img_size, this->img_size
792         ));
793
794         build_options opts;
795         if (runOnGPU)
796         {
797             opts.set_option(build_option::detection_output_gpu(true));
798         }
799
800         network network(engine, topology, opts);
801         network.set_input_data("input_location", input_location);
802         network.set_input_data("input_confidence", input_confidence);
803         network.set_input_data("input_prior_box", input_prior_box);
804
805         auto outputs = network.execute();
806
807         EXPECT_EQ(outputs.size(), size_t(1));
808         EXPECT_EQ(outputs.begin()->first, "detection_output");
809
810         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
811         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
812         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
813         EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
814
815         auto output_prim = outputs.begin()->second.get_memory();
816
817         check_results(output_prim, 0, "0 0 0.6 0.55 0.55 0.85 0.85");
818         check_results(output_prim, 1, "0 0 0.4 0.15 0.55 0.45 0.85");
819         check_results(output_prim, 2, "0 1 1.0 0.20 0.20 0.50 0.50");
820         check_results(output_prim, 3, "0 1 0.8 0.50 0.20 0.80 0.50");
821         check_results(output_prim, 4, "1 0 1.0 0.25 0.25 0.55 0.55");
822         check_results(output_prim, 5, "1 1 0.6 0.40 0.40 0.70 0.70");
823         check_results(output_prim, 6, "-1 0 0 0 0 0 0");
824         check_results(output_prim, 7, "-1 0 0 0 0 0 0");
825     }
826
827     static const int num_of_images = 2;
828     static const int num_classes = 2;
829     static const int num_priors = 4;
830     static const int img_size = 300;
831     const float nms_threshold;
832 };
833
834 typedef ::testing::Types<float, FLOAT16> detection_output_test_types;
835 TYPED_TEST_CASE(detection_output_test, detection_output_test_types);
836
837
838 TYPED_TEST(detection_output_test, test_setup_basic)
839 {
840     this->setup_basic(false);
841 }
842
843 TYPED_TEST(detection_output_test, test_setup_basic_gpu)
844 {
845     this->setup_basic(true);
846 }
847
848 TYPED_TEST(detection_output_test, test_setup_two_layers)
849 {
850     this->setup_two_layers(false);
851 }
852
853 TYPED_TEST(detection_output_test, test_setup_two_layers_gpu)
854 {
855     this->setup_two_layers(true);
856 }
857
858 TYPED_TEST(detection_output_test, test_forward_share_location)
859 {
860     this->forward_share_location(false);
861 }
862
863 TYPED_TEST(detection_output_test, test_forward_share_location_gpu)
864 {
865     this->forward_share_location(true);
866 }
867
868 TYPED_TEST(detection_output_test, test_forward_num_detections_greater_than_keep_top_k)
869 {
870     this->forward_num_detections_greater_than_keep_top_k(false);
871 }
872
873 TYPED_TEST(detection_output_test, test_forward_num_detections_greater_than_keep_top_k_gpu)
874 {
875     this->forward_num_detections_greater_than_keep_top_k(true);
876 }
877
878 TYPED_TEST(detection_output_test, test_forward_num_detections_smaller_than_keep_top_k)
879 {
880     this->forward_num_detections_smaller_than_keep_top_k(false);
881 }
882
883 TYPED_TEST(detection_output_test, test_forward_num_detections_smaller_than_keep_top_k_gpu)
884 {
885     this->forward_num_detections_smaller_than_keep_top_k(true);
886 }
887
888 TYPED_TEST(detection_output_test, test_forward_share_location_top_k)
889 {
890     this->test_forward_share_location_top_k(false);
891 }
892
893 TYPED_TEST(detection_output_test, test_forward_share_location_top_k_gpu)
894 {
895     this->test_forward_share_location_top_k(true);
896 }
897
898 TYPED_TEST(detection_output_test, test_forward_no_share_location)
899 {
900     this->forward_no_share_location(false);
901 }
902
903 TYPED_TEST(detection_output_test, test_forward_no_share_location_gpu)
904 {
905     this->forward_no_share_location(true);
906 }
907
908 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k)
909 {
910     this->forward_no_share_location_top_k(false);
911 }
912
913 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_gpu)
914 {
915     this->forward_no_share_location_top_k(true);
916 }
917
918 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0)
919 {
920     this->forward_no_share_location_neg_0(false);
921 }
922
923 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_gpu)
924 {
925     this->forward_no_share_location_neg_0(true);
926 }
927
928 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_top_k)
929 {
930     this->forward_no_share_location_neg_0_top_k(false);
931 }
932
933 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_top_k_gpu)
934 {
935     this->forward_no_share_location_neg_0_top_k(true);
936 }
937
938 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_input_padding)
939 {
940     this->forward_no_share_location_top_k_input_padding(false);
941 }
942
943 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_input_padding_gpu)
944 {
945     this->forward_no_share_location_top_k_input_padding(true);
946 }
947
948 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_faster_rcnn_case)
949 {
950     this->test_forward_no_share_location_top_k_faster_rcnn_case(false);
951 }
952
953 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_faster_rcnn_case_gpu)
954 {
955     this->test_forward_no_share_location_top_k_faster_rcnn_case(true);
956 }
957
958 TYPED_TEST(detection_output_test, test_detection_output_sort_gpu)
959 {
960     const bool share_location = false;
961     const int num_loc_classes = share_location ? 1 : this->num_classes;
962     const int keep_top_k = 10;
963     const int background_label_id = -1;
964     const int top_k = -1;
965
966     const unsigned out_row_size = 7;
967     const unsigned score_space = ((this->num_of_images + 15) / 16) * 16;
968     int input_size = this->num_of_images * num_loc_classes * this->num_priors * out_row_size + score_space;
969
970     const auto& engine = get_test_engine();
971     cldnn::memory input_buff = memory::allocate(engine, { type_to_data_type<TypeParam>::value, format::bfyx,{ 1, 1, 1, input_size } });
972
973     this->init_buffer_sort(input_buff);
974
975     topology topology;
976     topology.add(input_layout("input_location", input_buff.get_layout()));
977
978     topology.add(detection_output_sort("detection_output_sort", "input_location", this->num_of_images, this->num_classes, keep_top_k, share_location, top_k, background_label_id));
979     network network(engine, topology);
980     network.set_input_data("input_location", input_buff);
981
982     auto outputs = network.execute();
983
984     EXPECT_EQ(outputs.size(), size_t(1));
985     EXPECT_EQ(outputs.begin()->first, "detection_output_sort");
986
987     EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.batch[0], 1);
988     EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.feature[0], 1);
989     EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[1], keep_top_k * this->num_of_images);
990     EXPECT_EQ(outputs.begin()->second.get_memory().get_layout().size.spatial[0], 7);
991
992     auto output_prim = outputs.begin()->second.get_memory();
993
994     this->check_results(output_prim, 0, "0 0 0.6 0.55 0.55 0.85 0.85");
995     this->check_results(output_prim, 1, "0 0 0.4 0.15 0.55 0.45 0.85");
996     this->check_results(output_prim, 2, "0 0 0.2 0.55 0.15 0.85 0.45");
997     this->check_results(output_prim, 3, "0 0 0.0 0.15 0.15 0.45 0.45");
998     this->check_results(output_prim, 4, "0 1 1.0 0.20 0.20 0.50 0.50");
999     this->check_results(output_prim, 5, "0 1 0.8 0.50 0.20 0.80 0.50");
1000     this->check_results(output_prim, 6, "0 1 0.6 0.20 0.50 0.50 0.80");
1001     this->check_results(output_prim, 7, "0 1 0.4 0.50 0.50 0.80 0.80");
1002     this->check_results(output_prim, 8, "1 0 1.0 0.25 0.25 0.55 0.55");
1003     this->check_results(output_prim, 9, "1 0 0.4 0.45 0.45 0.75 0.75");
1004     this->check_results(output_prim, 10, "1 1 0.6 0.40 0.40 0.70 0.70");
1005     this->check_results(output_prim, 11, "-1 0 0 0 0 0 0");
1006     this->check_results(output_prim, 12, "-1 0 0 0 0 0 0");
1007     this->check_results(output_prim, 13, "-1 0 0 0 0 0 0");
1008     this->check_results(output_prim, 14, "-1 0 0 0 0 0 0");
1009     this->check_results(output_prim, 15, "-1 0 0 0 0 0 0");
1010     this->check_results(output_prim, 16, "-1 0 0 0 0 0 0");
1011     this->check_results(output_prim, 17, "-1 0 0 0 0 0 0");
1012     this->check_results(output_prim, 18, "-1 0 0 0 0 0 0");
1013     this->check_results(output_prim, 19, "-1 0 0 0 0 0 0");
1014 }
1015