2 // Copyright (c) 2016 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
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"
29 template<> struct type_to_data_type<FLOAT16> { static const data_types value = data_types::f16; };
32 using namespace cldnn;
33 using namespace tests;
36 class detection_output_test : public ::testing::Test
40 detection_output_test() :
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)
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>();
52 T* prior_data = prior_box_ptr.data();
53 T* confidence_data = confidence_ptr.data();
54 T* location_data = location_ptr.data();
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;
62 for (int h = 0; h < 2; ++h)
64 float center_y = (h + 0.5f) * step;
65 for (int w = 0; w < 2; ++w)
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;
73 idx += prior_info_size;
76 if (!variance_encoded_in_target)
78 for (int i = 0; i < idx; ++i)
80 prior_data[idx + i] = variance;
86 for (int i = 0; i < num_of_images; ++i)
88 for (int j = 0; j < num_priors; ++j)
90 for (int c = 0; c < num_classes; ++c)
94 confidence_data[idx++] = j * 0.2f;
98 confidence_data[idx++] = 1 - j * 0.2f;
105 const int num_loc_classes = share_location ? 1 : num_classes;
106 const float loc_multiplier = variance_encoded_in_target ? variance : 1.0f;
108 for (int i = 0; i < num_of_images; ++i)
110 for (int h = 0; h < 2; ++h)
112 for (int w = 0; w < 2; ++w)
114 for (int c = 0; c < num_loc_classes; ++c)
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;
126 void init_buffer_sort(cldnn::memory input_buff)
128 auto input_data_ptr = input_buff.pointer<T>();
130 EXPECT_EQ((int)input_buff.count(), 128);
132 T* input_data = input_data_ptr.data();
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;
153 void check_results(const memory& output, const int num, const std::string values)
155 assert(num < output.get_layout().size.spatial[1]);
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);
164 auto out_ptr = output.pointer<T>();
165 const T* data = out_ptr.data();
166 for (int i = 0; i < 2; ++i)
168 EXPECT_EQ(static_cast<int>((float)data[num * output.get_layout().size.spatial[0] + i]), atoi(items[i].c_str()));
170 for (int i = 2; i < 7; ++i)
172 EXPECT_TRUE(floating_point_equal(data[num * output.get_layout().size.spatial[0] + i], (T)(float)atof(items[i].c_str())));
176 void setup_basic(bool runOnGPU)
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;
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 } });
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()));
192 topology.add(detection_output("detection_output", "input_location", "input_confidence", "input_prior_box", this->num_classes, keep_top_k));
197 opts.set_option(build_option::detection_output_gpu(true));
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);
205 auto outputs = network.execute();
207 EXPECT_EQ(outputs.size(), size_t(1));
208 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
216 void setup_two_layers(bool runOnGPU)
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;
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 } });
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()));
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));
238 opts.set_option(build_option::detection_output_gpu(true));
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);
246 auto outputs = network.execute();
248 EXPECT_EQ(outputs.size(), size_t(2));
250 for (auto it = outputs.begin(); it != outputs.begin(); it++)
253 EXPECT_EQ(it->first, "detection_output_" + std::to_string(i));
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);
263 void forward_share_location(bool runOnGPU)
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;
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 } });
275 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
287 opts.set_option(build_option::detection_output_gpu(true));
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);
295 auto outputs = network.execute();
297 EXPECT_EQ(outputs.size(), size_t(1));
298 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
305 auto output_prim = outputs.begin()->second.get_memory();
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");
317 void forward_num_detections_greater_than_keep_top_k(bool runOnGPU)
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;
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 } });
329 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
341 opts.set_option(build_option::detection_output_gpu(true));
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);
349 auto outputs = network.execute();
351 EXPECT_EQ(outputs.size(), size_t(1));
352 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
359 auto output_prim = outputs.begin()->second.get_memory();
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");
365 void forward_num_detections_smaller_than_keep_top_k(bool runOnGPU)
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;
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 } });
377 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
389 opts.set_option(build_option::detection_output_gpu(true));
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);
397 auto outputs = network.execute();
399 EXPECT_EQ(outputs.size(), size_t(1));
400 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
407 auto output_prim = outputs.begin()->second.get_memory();
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");
423 void test_forward_share_location_top_k(bool runOnGPU)
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;
429 const int background_label_id = 0;
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 } });
436 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
448 opts.set_option(build_option::detection_output_gpu(true));
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);
456 auto outputs = network.execute();
458 EXPECT_EQ(outputs.size(), size_t(1));
459 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
466 auto output_prim = outputs.begin()->second.get_memory();
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");
474 void forward_no_share_location(bool runOnGPU)
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;
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 } });
486 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
498 opts.set_option(build_option::detection_output_gpu(true));
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);
506 auto outputs = network.execute();
508 EXPECT_EQ(outputs.size(), size_t(1));
509 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
516 auto output_prim = outputs.begin()->second.get_memory();
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");
540 void forward_no_share_location_top_k(bool runOnGPU)
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;
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 } });
553 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
565 opts.set_option(build_option::detection_output_gpu(true));
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);
573 auto outputs = network.execute();
575 EXPECT_EQ(outputs.size(), size_t(1));
576 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
583 auto output_prim = outputs.begin()->second.get_memory();
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");
595 void forward_no_share_location_neg_0(bool runOnGPU)
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;
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 } });
607 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
619 opts.set_option(build_option::detection_output_gpu(true));
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);
627 auto outputs = network.execute();
629 EXPECT_EQ(outputs.size(), size_t(1));
630 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
637 auto output_prim = outputs.begin()->second.get_memory();
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");
651 void forward_no_share_location_neg_0_top_k(bool runOnGPU)
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;
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 } });
664 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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()));
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));
676 opts.set_option(build_option::detection_output_gpu(true));
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);
684 auto outputs = network.execute();
686 EXPECT_EQ(outputs.size(), size_t(1));
687 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
694 auto output_prim = outputs.begin()->second.get_memory();
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");
702 void forward_no_share_location_top_k_input_padding(bool runOnGPU)
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;
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 } });
715 this->init_buffers(input_prior_box, input_confidence, input_location, share_location);
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 } })));
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));
728 opts.set_option(build_option::detection_output_gpu(true));
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);
736 auto outputs = network.execute();
738 EXPECT_EQ(outputs.size(), size_t(1));
739 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
746 auto output_prim = outputs.begin()->second.get_memory();
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");
758 void test_forward_no_share_location_top_k_faster_rcnn_case(bool runOnGPU)
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;
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;
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 } });
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);
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 } })));
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
797 opts.set_option(build_option::detection_output_gpu(true));
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);
805 auto outputs = network.execute();
807 EXPECT_EQ(outputs.size(), size_t(1));
808 EXPECT_EQ(outputs.begin()->first, "detection_output");
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);
815 auto output_prim = outputs.begin()->second.get_memory();
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");
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;
834 typedef ::testing::Types<float, FLOAT16> detection_output_test_types;
835 TYPED_TEST_CASE(detection_output_test, detection_output_test_types);
838 TYPED_TEST(detection_output_test, test_setup_basic)
840 this->setup_basic(false);
843 TYPED_TEST(detection_output_test, test_setup_basic_gpu)
845 this->setup_basic(true);
848 TYPED_TEST(detection_output_test, test_setup_two_layers)
850 this->setup_two_layers(false);
853 TYPED_TEST(detection_output_test, test_setup_two_layers_gpu)
855 this->setup_two_layers(true);
858 TYPED_TEST(detection_output_test, test_forward_share_location)
860 this->forward_share_location(false);
863 TYPED_TEST(detection_output_test, test_forward_share_location_gpu)
865 this->forward_share_location(true);
868 TYPED_TEST(detection_output_test, test_forward_num_detections_greater_than_keep_top_k)
870 this->forward_num_detections_greater_than_keep_top_k(false);
873 TYPED_TEST(detection_output_test, test_forward_num_detections_greater_than_keep_top_k_gpu)
875 this->forward_num_detections_greater_than_keep_top_k(true);
878 TYPED_TEST(detection_output_test, test_forward_num_detections_smaller_than_keep_top_k)
880 this->forward_num_detections_smaller_than_keep_top_k(false);
883 TYPED_TEST(detection_output_test, test_forward_num_detections_smaller_than_keep_top_k_gpu)
885 this->forward_num_detections_smaller_than_keep_top_k(true);
888 TYPED_TEST(detection_output_test, test_forward_share_location_top_k)
890 this->test_forward_share_location_top_k(false);
893 TYPED_TEST(detection_output_test, test_forward_share_location_top_k_gpu)
895 this->test_forward_share_location_top_k(true);
898 TYPED_TEST(detection_output_test, test_forward_no_share_location)
900 this->forward_no_share_location(false);
903 TYPED_TEST(detection_output_test, test_forward_no_share_location_gpu)
905 this->forward_no_share_location(true);
908 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k)
910 this->forward_no_share_location_top_k(false);
913 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_gpu)
915 this->forward_no_share_location_top_k(true);
918 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0)
920 this->forward_no_share_location_neg_0(false);
923 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_gpu)
925 this->forward_no_share_location_neg_0(true);
928 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_top_k)
930 this->forward_no_share_location_neg_0_top_k(false);
933 TYPED_TEST(detection_output_test, test_forward_no_share_location_neg_0_top_k_gpu)
935 this->forward_no_share_location_neg_0_top_k(true);
938 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_input_padding)
940 this->forward_no_share_location_top_k_input_padding(false);
943 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_input_padding_gpu)
945 this->forward_no_share_location_top_k_input_padding(true);
948 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_faster_rcnn_case)
950 this->test_forward_no_share_location_top_k_faster_rcnn_case(false);
953 TYPED_TEST(detection_output_test, test_forward_no_share_location_top_k_faster_rcnn_case_gpu)
955 this->test_forward_no_share_location_top_k_faster_rcnn_case(true);
958 TYPED_TEST(detection_output_test, test_detection_output_sort_gpu)
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;
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;
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 } });
973 this->init_buffer_sort(input_buff);
976 topology.add(input_layout("input_location", input_buff.get_layout()));
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);
982 auto outputs = network.execute();
984 EXPECT_EQ(outputs.size(), size_t(1));
985 EXPECT_EQ(outputs.begin()->first, "detection_output_sort");
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);
992 auto output_prim = outputs.begin()->second.get_memory();
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");