2 // Copyright (c) 2018 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 ///////////////////////////////////////////////////////////////////////////////////////////////////
21 #include "pass_manager.h"
22 #include "program_node.h"
23 #include "mutable_data_inst.h"
24 #include "concatenation_inst.h"
25 #include "scale_inst.h"
26 #include "tensor_type.h"
29 This pass checks if data formats (layouts) of output/input in hidden layers match.
30 If not than required reorder is added to the network.
34 Add a reorder in between node and usr with reorder_layout as layout
36 void add_required_reorders::add_reorder(program_impl& p, program_node* node, program_node* usr, layout reorder_layout)
39 auto new_reorder = std::make_shared<reorder>(node->id() + "_reorder_" + usr->id(),
42 auto& new_reorder_node = p.get_or_create(new_reorder);
44 //ToDo: add a method to program_impl class which adds an intermediate node given a node and its user
45 auto it = std::find(usr->get_dependencies().begin(), usr->get_dependencies().end(), node);
46 if (it == usr->get_dependencies().end())
48 throw error("Inconcistency in topology description: user of a node is not present among its dependecies.", CLDNN_ERROR);
50 auto idx = it - usr->get_dependencies().begin();
51 if (idx < 0 || (size_t)idx >= usr->get_dependencies().size())
53 throw error("Internal Error: container index out of range exception.", CLDNN_ERROR);
55 p.add_intermediate(new_reorder_node, *usr, idx);
58 void add_required_reorders::run(program_impl& p)
60 auto usr_itr = p.get_processing_order().begin();
61 while (usr_itr != p.get_processing_order().end())
63 auto& usr = *usr_itr++;
64 if (usr->get_dependencies().size() == 0)
65 continue; // only nodes with dependencies
66 if (usr->is_type<internal_primitive>() || usr->is_type<data>())
68 if (usr->type()->does_an_implementation_exist(p.get_engine(), *usr))
72 First check if there are non data flow dependencies for the primitive
73 if so then choose the same output format as the data
75 bool correct_layout_selected = false;
76 for (auto& node : usr->get_dependencies())
78 if (!node->is_in_data_flow())
81 ToDo: Here we should handle also the situation where primitive usr has data inputs in different formats
83 layout current_layout(usr->get_output_layout().data_type,
84 node->get_output_layout().format,
85 usr->get_output_layout().size);
86 usr->set_output_layout(current_layout);
87 if (usr->type()->does_possible_implementation_exist(p.get_engine(), *usr))
89 correct_layout_selected = true;
94 throw error("Internal Error: no layout format available for " + usr->id() +
95 " comaptible with " + node->id(), CLDNN_ERROR);
100 if (!correct_layout_selected) {
101 //This list of preffered layouts has been selected arbitrary due to developers' experience
102 cldnn::format preffered_layout_formats[]{
108 for (auto new_layout_format : preffered_layout_formats)
110 layout current_layout(usr->get_output_layout().data_type,
112 usr->get_output_layout().size);
113 usr->set_output_layout(current_layout);
114 if (usr->type()->does_possible_implementation_exist(p.get_engine(), *usr))
116 correct_layout_selected = true;
121 if (!correct_layout_selected) {
122 throw error("Internal Error: no implementation for " + usr->id() + " kernel which satisfies output format dependecies.", CLDNN_ERROR);
126 // layout is selected now add required reorders
127 auto dep_itr = usr->get_dependencies().begin();
128 while (dep_itr != usr->get_dependencies().end())
130 auto node = *dep_itr++;
131 //do not add a reorder if usr or node are reorders or does not belong to data_flow
132 if (!usr->is_type<reorder>() &&
133 !node->is_type<reorder>() &&
134 node->is_in_data_flow())
136 if ((usr->get_output_layout()!=node->get_output_layout()))
138 add_reorder(p, node, usr, usr->get_output_layout());