Publishing R3
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / proposal_cpu_test.cpp
1 /*
2 // Copyright (c) 2017 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 <fstream>
19
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"
29
30 namespace cldnn
31 {
32 template<> struct type_to_data_type<FLOAT16> { static const data_types value = data_types::f16; };
33 }
34
35 using namespace cldnn;
36 using namespace tests;
37 using namespace std;
38
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;
45
46 const float epsilon = 0.00025f;
47 const float epsilon_fp16 = 0.125f;
48
49 // !!!!!!!!
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
55 // !!!!!!!!
56
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";
61
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 };
73
74 template <typename Dtype>
75 class TestRunnerProposal
76 {
77     public:
78         TestRunnerProposal();
79
80         memory Run(std::vector<Dtype>& data, 
81                    std::vector<Dtype>& rois);
82
83     private:
84         engine _engine;
85         layout _cls_scores_layout;
86         layout _bbox_pred_layout;
87         layout _image_info_layout;
88         topology _topology;
89         proposal _test_layer;
90         std::unique_ptr<network> _network;
91 };
92
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, 
99                                         cls_scores_name, 
100                                         bbox_pred_name,
101                                         image_info_name,
102                                         max_proposals,
103                                         iou_threshold,
104                                         min_bbox_size,
105                                         feature_stride,
106                                         pre_nms_topn,
107                                         post_nms_topn,
108                                         ratios,
109                                         scales,
110                                         padding())
111 {    
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));
115
116     _topology.add(_test_layer);
117
118     _network.reset(new network(_engine, _topology));
119 }
120
121 template <typename Dtype>
122 memory TestRunnerProposal<Dtype>::Run(std::vector<Dtype>& cls_scores_vals, 
123                               std::vector<Dtype>& bbox_pred_vals)
124 {
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());
127
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);
132    
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);
136
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();    
140 }
141
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]);
145
146     TestRunnerProposal<float> t;
147
148     const memory& output = t.Run(cls_scores, bbox_pred);
149     ASSERT_EQ(output.get_layout().count(), proposal_ref_size);
150
151     auto f = output.pointer<float>();
152
153     for (size_t i = 0; i < proposal_ref_size; i++) {
154         EXPECT_NEAR(f[i], proposal_ref[i], epsilon);
155     }
156 }
157
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]);
161     
162     TestRunnerProposal<FLOAT16> t;
163
164     const memory& output = t.Run(cls_scores, bbox_pred);
165     ASSERT_EQ(output.get_layout().count(), proposal_ref_size);
166
167     auto d = output.pointer<FLOAT16>();
168
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);
172     }
173 }
174