Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / src / include / implementation_map.h
1 /*
2 // Copyright (c) 2016 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 #pragma once
17
18 #include <map>
19 #include <functional>
20 #include <typeinfo>
21
22 template<typename T, typename U>
23 class singleton_map : public std::map<T, U> {
24     singleton_map() : std::map<T, U>() {};
25     singleton_map(singleton_map const&) = delete;
26     void operator=(singleton_map const&) = delete;
27
28     public:
29     static singleton_map &instance() {
30         static singleton_map instance_;
31         return instance_;
32     }
33 };
34
35 namespace cldnn {
36
37 struct permute;
38 struct reorder;
39 struct custom_gpu_primitive;
40 struct generic_layer;
41 struct reshape;
42 struct data;
43 struct mutable_data;
44 struct input_layout;
45 struct prior_box;
46
47 struct primitive_impl;
48
49 template <class PType>
50 struct typed_program_node;
51
52 template<typename primitive_kind>
53 struct implementation_key 
54 {
55     typedef std::tuple<engine_types, data_types, format::type> type;
56     type operator()(engine_types engine_type, const typed_program_node<primitive_kind>& primitive)
57     {
58         return std::make_tuple(engine_type, primitive.get_dependency(0).get_output_layout().data_type, primitive.get_dependency(0).get_output_layout().format);
59     }
60     type operator()(engine_types engine_type, const layout& proposed_layout)
61     {
62         return std::make_tuple(engine_type, proposed_layout.data_type, proposed_layout.format);
63     }
64 };
65
66 template<>
67 struct implementation_key<permute>
68 {
69     typedef cldnn::engine_types type;
70     type operator()(engine_types engine_type, const typed_program_node<permute>&)
71     {
72         return engine_type;
73     }
74     type operator()(engine_types engine_type, const layout&)
75     {
76         return engine_type;
77     }
78 };
79
80 template<>
81 struct implementation_key<reorder>
82 {
83     typedef cldnn::engine_types type;
84     type operator()(engine_types engine_type, const typed_program_node<reorder>&)
85     {
86         return engine_type;
87     }
88     type operator()(engine_types engine_type, const layout&)
89     {
90         return engine_type;
91     }
92
93 };
94
95 template<>
96 struct implementation_key<generic_layer>
97 {
98     typedef cldnn::engine_types type;
99     type operator()(engine_types engine_type, const typed_program_node<generic_layer>&)
100     {
101         return engine_type;
102     }
103     type operator()(engine_types engine_type, const layout&)
104     {
105         return engine_type;
106     }
107
108 };
109
110 template<>
111 struct implementation_key<custom_gpu_primitive>
112 {
113     typedef cldnn::engine_types type;
114     type operator()(engine_types engine_type, const typed_program_node<custom_gpu_primitive>&)
115     {
116         return engine_type;
117     }
118     type operator()(engine_types engine_type, const layout&)
119     {
120         return engine_type;
121     }
122
123 };
124
125 template<>
126 struct implementation_key<reshape>
127 {
128     typedef cldnn::engine_types type;
129     type operator()(engine_types engine_type, const typed_program_node<reshape>&)
130     {
131         return engine_type;
132     }
133     type operator()(engine_types engine_type, const layout&)
134     {
135         return engine_type;
136     }
137
138 };
139
140 template<>
141 struct implementation_key<data>
142 {
143     typedef cldnn::engine_types type;
144     type operator()(engine_types engine_type, const typed_program_node<data>&)
145     {
146         return engine_type;
147     }
148     type operator()(engine_types engine_type, const layout&)
149     {
150         return engine_type;
151     }
152
153 };
154
155 template<>
156 struct implementation_key<mutable_data>
157 {
158     typedef cldnn::engine_types type;
159     type operator()(engine_types engine_type, const typed_program_node<mutable_data>&)
160     {
161         return engine_type;
162     }
163     type operator()(engine_types engine_type, const layout&)
164     {
165         return engine_type;
166     }
167 };
168
169 template<>
170 struct implementation_key<input_layout>
171 {
172     typedef cldnn::engine_types type;
173     type operator()(engine_types engine_type, const typed_program_node<input_layout>&)
174     {
175         return engine_type;
176     }
177     type operator()(engine_types engine_type, const layout&)
178     {
179         return engine_type;
180     }
181
182 };
183
184 template<>
185 struct implementation_key<prior_box>
186 {
187     typedef cldnn::engine_types type;
188     type operator()(engine_types engine_type, const typed_program_node<prior_box>&)
189     {
190         return engine_type;
191     }
192     type operator()(engine_types engine_type, const layout&)
193     {
194         return engine_type;
195     }
196 };
197
198 template<typename primitive_kind>
199 class implementation_map {
200 public:
201     using key_builder = implementation_key<primitive_kind>;
202     using key_type = typename key_builder::type;
203     using factory_type = std::function<primitive_impl*(const typed_program_node<primitive_kind>&)>;
204     using map_type = singleton_map<key_type, factory_type>;
205
206     static factory_type get(engine_types engine_type, const typed_program_node<primitive_kind>& primitive) {
207         // lookup in database; throw if not found 
208         auto key = key_builder()(engine_type, primitive);
209         auto it = map_type::instance().find(key);
210         if (it == std::end(map_type::instance())) 
211             throw std::runtime_error(
212                 std::string("implementation_map for ") + typeid(primitive_kind).name()
213                     + " could not find any implementation to match key");
214         // create implementation & attach it to result 
215         return it->second;
216     }
217
218     //check if for a given engine and type there exist an implementation
219     static bool check(engine_types engine_type, const typed_program_node<primitive_kind>& primitive)
220     {
221         auto key = key_builder()(engine_type, primitive);
222         auto it = map_type::instance().find(key);
223         if (it == std::end(map_type::instance()))
224             return false;
225         else
226             return true;
227     }
228
229     //check if there exists a kernel implementation of a primitive with output set it primitive's output layout
230     static bool check_io_eq(engine_types engine_type, const typed_program_node<primitive_kind>& primitive)
231     {
232         auto key = key_builder()(engine_type, primitive.get_output_layout());
233         auto it = map_type::instance().find(key);
234         if (it == std::end(map_type::instance()))
235             return false;
236         else
237             return true;
238     }
239
240     static void add(typename map_type::key_type key, factory_type factory) {
241         map_type::instance().insert({ key, factory });
242     }
243
244     static void add(std::initializer_list<typename map_type::value_type> il) {
245         map_type::instance().insert(il);
246     }
247 };
248 }