Merge pull request #14827 from YashasSamaga:cuda4dnn-csl-low
[platform/upstream/opencv.git] / modules / dnn / src / layers / blank_layer.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Copyright (C) 2017, Intel Corporation, all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 #include "../precomp.hpp"
43 #include "../op_cuda.hpp"
44 #include "../op_inf_engine.hpp"
45
46 #ifdef HAVE_CUDA
47 #include "../cuda4dnn/primitives/reshape.hpp"
48 using namespace cv::dnn::cuda4dnn;
49 #endif
50
51 namespace cv
52 {
53 namespace dnn
54 {
55 class BlankLayerImpl CV_FINAL : public BlankLayer
56 {
57 public:
58     BlankLayerImpl(const LayerParams& params)
59     {
60         setParamsFrom(params);
61     }
62
63     virtual bool supportBackend(int backendId) CV_OVERRIDE
64     {
65         return backendId == DNN_BACKEND_OPENCV ||
66                backendId == DNN_BACKEND_CUDA ||
67                (backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
68     }
69
70     bool getMemoryShapes(const std::vector<MatShape> &inputs,
71                          const int requiredOutputs,
72                          std::vector<MatShape> &outputs,
73                          std::vector<MatShape> &internals) const CV_OVERRIDE
74     {
75         Layer::getMemoryShapes(inputs, requiredOutputs, outputs, internals);
76         return true;
77     }
78
79 #ifdef HAVE_OPENCL
80     bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_)
81     {
82         std::vector<UMat> inputs;
83         std::vector<UMat> outputs;
84
85         inputs_.getUMatVector(inputs);
86         outputs_.getUMatVector(outputs);
87
88         for (int i = 0, n = outputs.size(); i < n; ++i)
89         {
90             void *src_handle = inputs[i].handle(ACCESS_READ);
91             void *dst_handle = outputs[i].handle(ACCESS_WRITE);
92             if (src_handle != dst_handle)
93                 inputs[i].copyTo(outputs[i]);
94         }
95
96         return true;
97     }
98 #endif
99
100     void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
101     {
102         CV_TRACE_FUNCTION();
103         CV_TRACE_ARG_VALUE(name, "name", name.c_str());
104
105         CV_OCL_RUN(IS_DNN_OPENCL_TARGET(preferableTarget),
106                    forward_ocl(inputs_arr, outputs_arr, internals_arr))
107
108         std::vector<Mat> inputs, outputs;
109         inputs_arr.getMatVector(inputs);
110         outputs_arr.getMatVector(outputs);
111
112         for (int i = 0, n = outputs.size(); i < n; ++i)
113             if (outputs[i].data != inputs[i].data)
114                 inputs[i].copyTo(outputs[i]);
115     }
116
117 #ifdef HAVE_CUDA
118     Ptr<BackendNode> initCUDA(
119         void *context_,
120         const std::vector<Ptr<BackendWrapper>>& inputs,
121         const std::vector<Ptr<BackendWrapper>>& outputs
122     ) override
123     {
124         auto context = reinterpret_cast<csl::CSLContext*>(context_);
125         return make_cuda_node<cuda4dnn::ReshapeOp>(preferableTarget, std::move(context->stream));
126     }
127 #endif
128
129 #ifdef HAVE_INF_ENGINE
130     virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >& inputs) CV_OVERRIDE
131     {
132         InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]);
133         std::vector<size_t> dims = input->getDims();
134         CV_Assert(!dims.empty());
135
136         InferenceEngine::Builder::Layer ieLayer(name);
137         ieLayer.setName(name);
138         if (preferableTarget == DNN_TARGET_MYRIAD)
139         {
140             ieLayer.setType("Copy");
141         }
142         else
143         {
144             ieLayer.setType("Split");
145             ieLayer.getParameters()["axis"] = dims.size() - 1;
146             ieLayer.getParameters()["out_sizes"] = dims[0];
147         }
148         ieLayer.setInputPorts({InferenceEngine::Port(dims)});
149         ieLayer.setOutputPorts(std::vector<InferenceEngine::Port>(1));
150         return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
151     }
152 #endif  // HAVE_INF_ENGINE
153 };
154
155 Ptr<Layer> BlankLayer::create(const LayerParams& params)
156 {
157     // In case of Caffe's Dropout layer from Faster-RCNN framework,
158     // https://github.com/rbgirshick/caffe-fast-rcnn/tree/faster-rcnn
159     // return Power layer.
160     if (!params.get<bool>("scale_train", true))
161     {
162         float scale = 1 - params.get<float>("dropout_ratio", 0.5f);
163         CV_Assert(scale > 0);
164
165         LayerParams powerParams;
166         powerParams.name = params.name;
167         powerParams.type = "Power";
168         powerParams.set("scale", scale);
169
170         return PowerLayer::create(powerParams);
171     }
172     else
173         return Ptr<BlankLayer>(new BlankLayerImpl(params));
174 }
175
176 }
177 }