dab8ba8b317b4493b9d711cd9c2db39b1f83e8f9
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / src / graph_optimizer / prepare_depthwise_sep_opt.cpp
1 /*
2 // Copyright (c) 2018 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
19 #include "pass_manager.h"
20 #include "program_helpers.h"
21
22 template <typename T>
23 void prepare_depthwise_sep_opt::optimize_depthwise_sep_pre(T& node) {
24     if (node.get_groups() == 1) {
25         // enable optimization only when IFM / split <= 8 (otherwise scheduling multiple opt kernels is better) and
26         // split >= 16
27         if (!(node.get_dependency(0).get_output_layout().size.feature[0] / node.get_primitive()->split() <= 8) ||
28             !(node.get_primitive()->split() >= 16))
29             return;
30
31         // make sure the weights and biases are data type and
32         // are not reused in other primitives as they will be overriden with concatenated ones
33         for (size_t i = 1; i < node.get_dependencies().size(); i++) {
34             auto& weights_or_biases = node.get_dependency(i);
35             if (weights_or_biases.get_users().size() > 1 || weights_or_biases.type() != data::type_id())
36                 return;
37         }
38     } else {
39         // enable optimization only when IFM / groups <= 8 (otherwise scheduling multiple opt kernels is better) and
40         // groups >= 16
41         if (!(node.get_dependency(0).get_output_layout().size.feature[0] / node.get_groups() <= 8) ||
42             !(node.get_groups() >= 16))
43             return;
44     }
45
46     node.set_depthwise_sep_opt(true);
47 }
48
49 template void prepare_depthwise_sep_opt::optimize_depthwise_sep_pre<convolution_node>(convolution_node& node);
50 template void prepare_depthwise_sep_opt::optimize_depthwise_sep_pre<deconvolution_node>(deconvolution_node& node);
51
52 void prepare_depthwise_sep_opt::run(program_impl& p) {
53     // depthiwise separated convolution/deconvolution optimization
54     for (auto& prim : p.get_processing_order()) {
55         if (prim->type() == convolution::type_id()) {
56             optimize_depthwise_sep_pre(prim->as<convolution>());
57         } else if (prim->type() == deconvolution::type_id()) {
58             optimize_depthwise_sep_pre(prim->as<deconvolution>());
59         }
60     }
61 }