Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / extension / ext_priorbox_clustered.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include "ext_list.hpp"
6 #include "ext_base.hpp"
7 #include <algorithm>
8 #include <vector>
9
10 namespace InferenceEngine {
11 namespace Extensions {
12 namespace Cpu {
13
14 class PriorBoxClusteredImpl: public ExtLayerBase {
15 public:
16     explicit PriorBoxClusteredImpl(const CNNLayer* layer) {
17         try {
18             if (layer->insData.size() != 2 || layer->outData.empty())
19                 THROW_IE_EXCEPTION << "Incorrect number of input/output edges!";
20
21             if (layer->insData[0].lock()->dims.size() != 4 ||
22                     layer->insData[1].lock()->dims.size() != 4)
23                 THROW_IE_EXCEPTION << "PriorBoxClustered supports only 4D blobs!";
24
25             widths_ = layer->GetParamAsFloats("width", {});
26             heights_ = layer->GetParamAsFloats("height", {});
27             clip_ = layer->GetParamAsInt("clip");
28             variance_ = layer->GetParamAsFloats("variance", {});
29             img_h_ = layer->GetParamAsInt("img_h", 0);
30             img_w_ = layer->GetParamAsInt("img_w", 0);
31             step_ = layer->GetParamAsFloat("step", 0);
32             step_h_ = layer->GetParamAsFloat("step_h", 0);
33             step_w_ = layer->GetParamAsFloat("step_w", 0);
34             offset_ = layer->GetParamAsFloat("offset");
35
36             addConfig(layer, {{ConfLayout::PLN, true}, {ConfLayout::PLN, true}}, {{ConfLayout::PLN, true}});
37         } catch (InferenceEngine::details::InferenceEngineException &ex) {
38             errorMsg = ex.what();
39         }
40     }
41
42     StatusCode init(LayerConfig& config, ResponseDesc *resp) noexcept override {
43         return OK;
44     }
45
46     StatusCode execute(std::vector<Blob::Ptr>& inputs, std::vector<Blob::Ptr>& outputs,
47                        ResponseDesc *resp) noexcept override {
48         int num_priors_ = widths_.size();
49
50         if (variance_.empty())
51             variance_.push_back(0.1f);
52
53         // Execute
54         const int layer_width = inputs[0]->getTensorDesc().getDims()[3];
55         const int layer_height = inputs[0]->getTensorDesc().getDims()[2];
56
57         int img_width = img_w_ == 0 ? inputs[1]->getTensorDesc().getDims()[3] : img_w_;
58         int img_height = img_h_ == 0 ? inputs[1]->getTensorDesc().getDims()[2] : img_h_;
59
60         float step_w = step_w_ == 0 ? step_ : step_w_;
61         float step_h = step_h_ == 0 ? step_ : step_h_;
62         if (step_w == 0 && step_h == 0) {
63             step_w = static_cast<float>(img_width) / layer_width;
64             step_h = static_cast<float>(img_height) / layer_height;
65         }
66
67         auto *top_data_0 = outputs[0]->buffer().as<float *>();
68         float *top_data_1 = top_data_0 + outputs[0]->getTensorDesc().getDims()[2];
69         int var_size = variance_.size();
70
71         for (int h = 0; h < layer_height; ++h) {
72             for (int w = 0; w < layer_width; ++w) {
73                 float center_x = (w + offset_) * step_w;
74                 float center_y = (h + offset_) * step_h;
75
76                 for (int s = 0; s < num_priors_; ++s) {
77                     float box_width = widths_[s];
78                     float box_height = heights_[s];
79
80                     float xmin = (center_x - box_width / 2.0f) / img_width;
81                     float ymin = (center_y - box_height / 2.0f) / img_height;
82                     float xmax = (center_x + box_width / 2.0f) / img_width;
83                     float ymax = (center_y + box_height / 2.0f) / img_height;
84
85                     if (clip_) {
86                         xmin = std::min(std::max(xmin, 0.0f), 1.0f);
87                         ymin = std::min(std::max(ymin, 0.0f), 1.0f);
88                         xmax = std::min(std::max(xmax, 0.0f), 1.0f);
89                         ymax = std::min(std::max(ymax, 0.0f), 1.0f);
90                     }
91
92                     top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 0] = xmin;
93                     top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 1] = ymin;
94                     top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 2] = xmax;
95                     top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 3] = ymax;
96
97                     for (int j = 0; j < var_size; j++)
98                         top_data_1[h * layer_width * num_priors_ * var_size + w * num_priors_ * var_size +
99                                    s * var_size +
100                                    j] = variance_[j];
101                 }
102             }
103         }
104         return OK;
105     }
106
107 private:
108     std::vector<float> widths_;
109     std::vector<float> heights_;
110     std::vector<float> variance_;
111     int clip_;
112     int img_h_;
113     int img_w_;
114     float step_;
115     float step_h_;
116     float step_w_;
117     float offset_;
118 };
119
120 REG_FACTORY_FOR(ImplFactory<PriorBoxClusteredImpl>, PriorBoxClustered);
121
122 }  // namespace Cpu
123 }  // namespace Extensions
124 }  // namespace InferenceEngine