2 // Copyright (c) 2017 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 ///////////////////////////////////////////////////////////////////////////////////////////////////
20 #include <gtest/gtest.h>
21 #include "api/CPP/memory.hpp"
22 #include <api/CPP/input_layout.hpp>
23 #include <api/CPP/proposal.hpp>
24 #include <api/CPP/topology.hpp>
25 #include <api/CPP/network.hpp>
26 #include <api/CPP/engine.hpp>
27 #include "test_utils/test_utils.h"
28 #include "test_utils/float16.h"
32 template<> struct type_to_data_type<FLOAT16> { static const data_types value = data_types::f16; };
35 using namespace cldnn;
36 using namespace tests;
39 extern float cls_scores_data[];
40 extern size_t cls_scores_data_size;
41 extern float bbox_pred_data[];
42 extern size_t bbox_pred_data_size;
43 extern float proposal_ref[];
44 extern size_t proposal_ref_size;
46 const float epsilon = 0.00025f;
47 const float epsilon_fp16 = 0.125f;
50 // The data for this test (input and ref) was generated in clCaffe using the zf truncated prototxt with the following modifications:
51 // input height: 420 -> 210
52 // input width: 700 -> 350
53 // max proposals: 300 -> 50
54 // post nms topn: 150 -> 25
57 const primitive_id cls_scores_name = "cls_scores";
58 const primitive_id bbox_pred_name = "bbox_pred";
59 const primitive_id image_info_name = "image_info";
60 const primitive_id layer_name = "proposal";
62 const int max_proposals = 50;
63 const float iou_threshold = 0.7f;
64 const int min_bbox_size = 16;
65 const int feature_stride = 16;
66 const int pre_nms_topn = 6000;
67 const int post_nms_topn = 25;
68 const int image_w = 350;
69 const int image_h = 210;
70 const int image_z = 1;
71 const std::vector<float> ratios = { 0.5f, 1.0f, 2.0f };
72 const std::vector<float> scales = { 8.0f, 16.0f, 32.0f };
74 template <typename Dtype>
75 class TestRunnerProposal
80 memory Run(std::vector<Dtype>& data,
81 std::vector<Dtype>& rois);
85 layout _cls_scores_layout;
86 layout _bbox_pred_layout;
87 layout _image_info_layout;
90 std::unique_ptr<network> _network;
93 template <typename Dtype>
94 TestRunnerProposal<Dtype>::TestRunnerProposal() :
95 _cls_scores_layout(cldnn::type_to_data_type<Dtype>::value, format::bfyx, { 1, 18, 23, 14 } ),
96 _bbox_pred_layout(cldnn::type_to_data_type<Dtype>::value, format::bfyx, { 1, 36, 23, 14 } ),
97 _image_info_layout(cldnn::type_to_data_type<Dtype>::value, format::bfyx, { 1, 1, 3, 1 } ),
98 _test_layer(layer_name,
112 _topology.add(input_layout(cls_scores_name, _cls_scores_layout));
113 _topology.add(input_layout(bbox_pred_name, _bbox_pred_layout));
114 _topology.add(input_layout(image_info_name, _image_info_layout));
116 _topology.add(_test_layer);
118 _network.reset(new network(_engine, _topology));
121 template <typename Dtype>
122 memory TestRunnerProposal<Dtype>::Run(std::vector<Dtype>& cls_scores_vals,
123 std::vector<Dtype>& bbox_pred_vals)
125 memory cls_scores = memory::attach(_cls_scores_layout, cls_scores_vals.data(), cls_scores_vals.size());
126 memory bbox_pred = memory::attach(_bbox_pred_layout, bbox_pred_vals.data(), bbox_pred_vals.size());
128 Dtype image_info_vals[] = { (Dtype)((float)image_h - 0.0000001f), // check fp robustness of the layer
129 (Dtype)((float)image_w + 0.0000001f), // check fp robustness of the layer
130 (Dtype)((float)image_z) };
131 memory image_info = memory::attach(_image_info_layout, &image_info_vals[0], 3);
133 _network->set_input_data(cls_scores_name, cls_scores);
134 _network->set_input_data(bbox_pred_name, bbox_pred);
135 _network->set_input_data(image_info_name, image_info);
137 std::map<primitive_id, network_output> network_output = _network->execute();
138 EXPECT_EQ(network_output.begin()->first, layer_name);
139 return network_output.at(layer_name).get_memory();
142 TEST(proposal, basic) {
143 std::vector<float> cls_scores(&cls_scores_data[0], &cls_scores_data[cls_scores_data_size]);
144 std::vector<float> bbox_pred(&bbox_pred_data[0], &bbox_pred_data[bbox_pred_data_size]);
146 TestRunnerProposal<float> t;
148 const memory& output = t.Run(cls_scores, bbox_pred);
149 ASSERT_EQ(output.get_layout().count(), proposal_ref_size);
151 auto f = output.pointer<float>();
153 for (size_t i = 0; i < proposal_ref_size; i++) {
154 EXPECT_NEAR(f[i], proposal_ref[i], epsilon);
158 TEST(proposal, fp16) {
159 std::vector<FLOAT16> cls_scores(&cls_scores_data[0], &cls_scores_data[cls_scores_data_size]);
160 std::vector<FLOAT16> bbox_pred(&bbox_pred_data[0], &bbox_pred_data[bbox_pred_data_size]);
162 TestRunnerProposal<FLOAT16> t;
164 const memory& output = t.Run(cls_scores, bbox_pred);
165 ASSERT_EQ(output.get_layout().count(), proposal_ref_size);
167 auto d = output.pointer<FLOAT16>();
169 for (size_t i = 0; i < proposal_ref_size; i++) {
170 FLOAT16 ref(proposal_ref[i]);
171 EXPECT_NEAR((float)d[i], (float)ref, epsilon_fp16);