1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 //
5 // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // https://opensource.org/licenses/BSD-3-Clause
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14
15 #include "layer.h"
16
17 #include "cpu.h"
18
19 #include <math.h>
20 #include <string.h>
21
22 #ifdef _MSC_VER
23 #pragma warning(push)
24 #pragma warning(disable : 4250)
25 #endif
26 #ifdef __clang__
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Woverloaded-virtual"
29 #endif
30 #include "layer_declaration.h"
31 #ifdef __clang__
32 #pragma clang diagnostic pop
33 #endif
34 #ifdef _MSC_VER
35 #pragma warning(pop)
36 #endif
37
38 namespace ncnn {
39
Layer()40 Layer::Layer()
41 {
42 one_blob_only = false;
43 support_inplace = false;
44 support_vulkan = false;
45 support_packing = false;
46
47 support_bf16_storage = false;
48 support_fp16_storage = false;
49 support_int8_storage = false;
50 support_image_storage = false;
51 support_tensor_storage = false;
52
53 support_weight_fp16_storage = false;
54
55 typeindex = -1;
56
57 #if NCNN_VULKAN
58 vkdev = 0;
59 #endif // NCNN_VULKAN
60
61 userdata = 0;
62 }
63
~Layer()64 Layer::~Layer()
65 {
66 }
67
load_param(const ParamDict &)68 int Layer::load_param(const ParamDict& /*pd*/)
69 {
70 return 0;
71 }
72
load_model(const ModelBin &)73 int Layer::load_model(const ModelBin& /*mb*/)
74 {
75 return 0;
76 }
77
create_pipeline(const Option &)78 int Layer::create_pipeline(const Option& /*opt*/)
79 {
80 return 0;
81 }
82
destroy_pipeline(const Option &)83 int Layer::destroy_pipeline(const Option& /*opt*/)
84 {
85 return 0;
86 }
87
forward(const std::vector<Mat> & bottom_blobs,std::vector<Mat> & top_blobs,const Option & opt) const88 int Layer::forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const
89 {
90 if (!support_inplace)
91 return -1;
92
93 top_blobs = bottom_blobs;
94 for (int i = 0; i < (int)top_blobs.size(); i++)
95 {
96 top_blobs[i] = bottom_blobs[i].clone(opt.blob_allocator);
97 if (top_blobs[i].empty())
98 return -100;
99 }
100
101 return forward_inplace(top_blobs, opt);
102 }
103
forward(const Mat & bottom_blob,Mat & top_blob,const Option & opt) const104 int Layer::forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const
105 {
106 if (!support_inplace)
107 return -1;
108
109 top_blob = bottom_blob.clone(opt.blob_allocator);
110 if (top_blob.empty())
111 return -100;
112
113 return forward_inplace(top_blob, opt);
114 }
115
forward_inplace(std::vector<Mat> &,const Option &) const116 int Layer::forward_inplace(std::vector<Mat>& /*bottom_top_blobs*/, const Option& /*opt*/) const
117 {
118 return -1;
119 }
120
forward_inplace(Mat &,const Option &) const121 int Layer::forward_inplace(Mat& /*bottom_top_blob*/, const Option& /*opt*/) const
122 {
123 return -1;
124 }
125
126 #if NCNN_VULKAN
upload_model(VkTransfer &,const Option &)127 int Layer::upload_model(VkTransfer& /*cmd*/, const Option& /*opt*/)
128 {
129 return 0;
130 }
131
forward(const std::vector<VkMat> & bottom_blobs,std::vector<VkMat> & top_blobs,VkCompute & cmd,const Option & opt) const132 int Layer::forward(const std::vector<VkMat>& bottom_blobs, std::vector<VkMat>& top_blobs, VkCompute& cmd, const Option& opt) const
133 {
134 if (!support_inplace)
135 return -1;
136
137 top_blobs.resize(bottom_blobs.size());
138 for (int i = 0; i < (int)top_blobs.size(); i++)
139 {
140 cmd.record_clone(bottom_blobs[i], top_blobs[i], opt);
141 }
142
143 return forward_inplace(top_blobs, cmd, opt);
144 }
145
forward(const VkMat & bottom_blob,VkMat & top_blob,VkCompute & cmd,const Option & opt) const146 int Layer::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
147 {
148 if (!support_inplace)
149 return -1;
150
151 cmd.record_clone(bottom_blob, top_blob, opt);
152
153 return forward_inplace(top_blob, cmd, opt);
154 }
155
forward(const std::vector<VkImageMat> & bottom_blobs,std::vector<VkImageMat> & top_blobs,VkCompute & cmd,const Option & opt) const156 int Layer::forward(const std::vector<VkImageMat>& bottom_blobs, std::vector<VkImageMat>& top_blobs, VkCompute& cmd, const Option& opt) const
157 {
158 if (!support_inplace)
159 return -1;
160
161 top_blobs.resize(bottom_blobs.size());
162 for (int i = 0; i < (int)top_blobs.size(); i++)
163 {
164 cmd.record_clone(bottom_blobs[i], top_blobs[i], opt);
165 }
166
167 return forward_inplace(top_blobs, cmd, opt);
168 }
169
forward(const VkImageMat & bottom_blob,VkImageMat & top_blob,VkCompute & cmd,const Option & opt) const170 int Layer::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const
171 {
172 if (!support_inplace)
173 return -1;
174
175 cmd.record_clone(bottom_blob, top_blob, opt);
176
177 return forward_inplace(top_blob, cmd, opt);
178 }
179
forward_inplace(std::vector<VkMat> &,VkCompute &,const Option &) const180 int Layer::forward_inplace(std::vector<VkMat>& /*bottom_top_blobs*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
181 {
182 return -1;
183 }
184
forward_inplace(VkMat &,VkCompute &,const Option &) const185 int Layer::forward_inplace(VkMat& /*bottom_top_blob*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
186 {
187 return -1;
188 }
189
forward_inplace(std::vector<VkImageMat> &,VkCompute &,const Option &) const190 int Layer::forward_inplace(std::vector<VkImageMat>& /*bottom_top_blobs*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
191 {
192 return -1;
193 }
194
forward_inplace(VkImageMat &,VkCompute &,const Option &) const195 int Layer::forward_inplace(VkImageMat& /*bottom_top_blob*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
196 {
197 return -1;
198 }
199 #endif // NCNN_VULKAN
200
201 static const layer_registry_entry layer_registry[] = {
202 #include "layer_registry.h"
203 };
204
205 #if NCNN_RUNTIME_CPU && NCNN_AVX2
206 static const layer_registry_entry layer_registry_avx2[] = {
207 #include "layer_registry_avx2.h"
208 };
209 #endif // NCNN_RUNTIME_CPU && NCNN_AVX2
210
211 #if NCNN_RUNTIME_CPU && NCNN_ARM82
212 static const layer_registry_entry layer_registry_arm82[] = {
213 #include "layer_registry_arm82.h"
214 };
215 #endif // NCNN_RUNTIME_CPU && NCNN_ARM82
216
217 static const int layer_registry_entry_count = sizeof(layer_registry) / sizeof(layer_registry_entry);
218
219 #if NCNN_STRING
layer_to_index(const char * type)220 int layer_to_index(const char* type)
221 {
222 for (int i = 0; i < layer_registry_entry_count; i++)
223 {
224 if (strcmp(type, layer_registry[i].name) == 0)
225 return i;
226 }
227
228 return -1;
229 }
230
create_layer(const char * type)231 Layer* create_layer(const char* type)
232 {
233 int index = layer_to_index(type);
234 if (index == -1)
235 return 0;
236
237 return create_layer(index);
238 }
239 #endif // NCNN_STRING
240
create_layer(int index)241 Layer* create_layer(int index)
242 {
243 if (index < 0 || index >= layer_registry_entry_count)
244 return 0;
245
246 // clang-format off
247 // *INDENT-OFF*
248 layer_creator_func layer_creator = 0;
249 #if NCNN_RUNTIME_CPU && NCNN_AVX2
250 if (ncnn::cpu_support_x86_avx2())
251 {
252 layer_creator = layer_registry_avx2[index].creator;
253 }
254 else
255 #endif // NCNN_RUNTIME_CPU && NCNN_AVX2
256 #if NCNN_RUNTIME_CPU && NCNN_ARM82
257 if (ncnn::cpu_support_arm_asimdhp())
258 {
259 layer_creator = layer_registry_arm82[index].creator;
260 }
261 else
262 #endif // NCNN_RUNTIME_CPU && NCNN_ARM82
263 {
264 layer_creator = layer_registry[index].creator;
265 }
266 // *INDENT-ON*
267 // clang-format on
268 if (!layer_creator)
269 return 0;
270
271 Layer* layer = layer_creator(0);
272 layer->typeindex = index;
273 return layer;
274 }
275
276 } // namespace ncnn
277