ncnn

Форк
0
/
layer.cpp 
590 строк · 14.5 Кб
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 <string.h>
20

21
#include "layer_declaration.h"
22

23
namespace ncnn {
24

25
Layer::Layer()
26
{
27
    one_blob_only = false;
28
    support_inplace = false;
29
    support_vulkan = false;
30
    support_packing = false;
31

32
    support_bf16_storage = false;
33
    support_fp16_storage = false;
34
    support_int8_storage = false;
35
    support_image_storage = false;
36
    support_tensor_storage = false;
37

38
    support_reserved_00 = false;
39

40
    typeindex = -1;
41

42
#if NCNN_VULKAN
43
    vkdev = 0;
44
#endif // NCNN_VULKAN
45

46
    userdata = 0;
47
}
48

49
Layer::~Layer()
50
{
51
}
52

53
int Layer::load_param(const ParamDict& /*pd*/)
54
{
55
    return 0;
56
}
57

58
int Layer::load_model(const ModelBin& /*mb*/)
59
{
60
    return 0;
61
}
62

63
int Layer::create_pipeline(const Option& /*opt*/)
64
{
65
    return 0;
66
}
67

68
int Layer::destroy_pipeline(const Option& /*opt*/)
69
{
70
    return 0;
71
}
72

73
int Layer::forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const
74
{
75
    if (!support_inplace)
76
        return -1;
77

78
    top_blobs = bottom_blobs;
79
    for (int i = 0; i < (int)top_blobs.size(); i++)
80
    {
81
        top_blobs[i] = bottom_blobs[i].clone(opt.blob_allocator);
82
        if (top_blobs[i].empty())
83
            return -100;
84
    }
85

86
    return forward_inplace(top_blobs, opt);
87
}
88

89
int Layer::forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const
90
{
91
    if (!support_inplace)
92
        return -1;
93

94
    top_blob = bottom_blob.clone(opt.blob_allocator);
95
    if (top_blob.empty())
96
        return -100;
97

98
    return forward_inplace(top_blob, opt);
99
}
100

101
int Layer::forward_inplace(std::vector<Mat>& /*bottom_top_blobs*/, const Option& /*opt*/) const
102
{
103
    return -1;
104
}
105

106
int Layer::forward_inplace(Mat& /*bottom_top_blob*/, const Option& /*opt*/) const
107
{
108
    return -1;
109
}
110

111
#if NCNN_VULKAN
112
int Layer::upload_model(VkTransfer& /*cmd*/, const Option& /*opt*/)
113
{
114
    return 0;
115
}
116

117
int Layer::forward(const std::vector<VkMat>& bottom_blobs, std::vector<VkMat>& top_blobs, VkCompute& cmd, const Option& opt) const
118
{
119
    if (!support_inplace)
120
        return -1;
121

122
    top_blobs.resize(bottom_blobs.size());
123
    for (int i = 0; i < (int)top_blobs.size(); i++)
124
    {
125
        cmd.record_clone(bottom_blobs[i], top_blobs[i], opt);
126
    }
127

128
    return forward_inplace(top_blobs, cmd, opt);
129
}
130

131
int Layer::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
132
{
133
    if (!support_inplace)
134
        return -1;
135

136
    cmd.record_clone(bottom_blob, top_blob, opt);
137

138
    return forward_inplace(top_blob, cmd, opt);
139
}
140

141
int Layer::forward(const std::vector<VkImageMat>& bottom_blobs, std::vector<VkImageMat>& top_blobs, VkCompute& cmd, const Option& opt) const
142
{
143
    if (!support_inplace)
144
        return -1;
145

146
    top_blobs.resize(bottom_blobs.size());
147
    for (int i = 0; i < (int)top_blobs.size(); i++)
148
    {
149
        cmd.record_clone(bottom_blobs[i], top_blobs[i], opt);
150
    }
151

152
    return forward_inplace(top_blobs, cmd, opt);
153
}
154

155
int Layer::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const
156
{
157
    if (!support_inplace)
158
        return -1;
159

160
    cmd.record_clone(bottom_blob, top_blob, opt);
161

162
    return forward_inplace(top_blob, cmd, opt);
163
}
164

165
int Layer::forward_inplace(std::vector<VkMat>& /*bottom_top_blobs*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
166
{
167
    return -1;
168
}
169

170
int Layer::forward_inplace(VkMat& /*bottom_top_blob*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
171
{
172
    return -1;
173
}
174

175
int Layer::forward_inplace(std::vector<VkImageMat>& /*bottom_top_blobs*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
176
{
177
    return -1;
178
}
179

180
int Layer::forward_inplace(VkImageMat& /*bottom_top_blob*/, VkCompute& /*cmd*/, const Option& /*opt*/) const
181
{
182
    return -1;
183
}
184
#endif // NCNN_VULKAN
185

186
#include "layer_registry.h"
187

188
static const int layer_registry_entry_count = sizeof(layer_registry) / sizeof(layer_registry_entry);
189

190
#if NCNN_STRING
191
int layer_to_index(const char* type)
192
{
193
    for (int i = 0; i < layer_registry_entry_count; i++)
194
    {
195
        if (strcmp(type, layer_registry[i].name) == 0)
196
            return i;
197
    }
198

199
    return -1;
200
}
201

202
Layer* create_layer(const char* type)
203
{
204
    int index = layer_to_index(type);
205
    if (index == -1)
206
        return 0;
207

208
    return create_layer(index);
209
}
210

211
Layer* create_layer_naive(const char* type)
212
{
213
    int index = layer_to_index(type);
214
    if (index == -1)
215
        return 0;
216

217
    return create_layer_naive(index);
218
}
219

220
Layer* create_layer_cpu(const char* type)
221
{
222
    int index = layer_to_index(type);
223
    if (index == -1)
224
        return 0;
225

226
    return create_layer_cpu(index);
227
}
228

229
#if NCNN_VULKAN
230
Layer* create_layer_vulkan(const char* type)
231
{
232
    int index = layer_to_index(type);
233
    if (index == -1)
234
        return 0;
235

236
    return create_layer_vulkan(index);
237
}
238
#endif // NCNN_VULKAN
239
#endif // NCNN_STRING
240

241
// internal wrapper
242
class Layer_final : public Layer
243
{
244
public:
245
    Layer* layer_cpu;
246
#if NCNN_VULKAN
247
    Layer* layer_vulkan;
248
#endif
249

250
    // utility functions for transfer layer properties
251
    void set_layer_properties()
252
    {
253
        layer_cpu->userdata = userdata;
254

255
        layer_cpu->bottoms = bottoms;
256
        layer_cpu->tops = tops;
257
        layer_cpu->bottom_shapes = bottom_shapes;
258
        layer_cpu->top_shapes = top_shapes;
259
        layer_cpu->featmask = featmask;
260

261
#if NCNN_VULKAN
262
        if (layer_vulkan)
263
        {
264
            layer_vulkan->vkdev = vkdev;
265

266
            layer_vulkan->userdata = userdata;
267

268
            layer_vulkan->bottoms = bottoms;
269
            layer_vulkan->tops = tops;
270
            layer_vulkan->bottom_shapes = bottom_shapes;
271
            layer_vulkan->top_shapes = top_shapes;
272
            layer_vulkan->featmask = featmask;
273
        }
274
#endif
275
    }
276

277
    void get_layer_properties()
278
    {
279
        one_blob_only = layer_cpu->one_blob_only;
280
        support_inplace = layer_cpu->support_inplace;
281
        support_packing = layer_cpu->support_packing;
282
        support_bf16_storage = layer_cpu->support_bf16_storage;
283
        support_fp16_storage = layer_cpu->support_fp16_storage;
284
        support_int8_storage = layer_cpu->support_int8_storage;
285

286
        support_vulkan = 0;
287
        support_image_storage = 0;
288
        support_tensor_storage = 0;
289

290
#if NCNN_VULKAN
291
        if (layer_vulkan)
292
        {
293
            support_vulkan = layer_vulkan->support_vulkan;
294
            support_image_storage = layer_vulkan->support_image_storage;
295
            support_tensor_storage = layer_vulkan->support_tensor_storage;
296
        }
297
#endif
298
    }
299

300
public:
301
    Layer_final()
302
    {
303
        layer_cpu = 0;
304
#if NCNN_VULKAN
305
        layer_vulkan = 0;
306
#endif
307
    }
308

309
    ~Layer_final()
310
    {
311
        delete layer_cpu;
312
#if NCNN_VULKAN
313
        delete layer_vulkan;
314
#endif
315
    }
316

317
    virtual int load_param(const ParamDict& pd)
318
    {
319
        set_layer_properties();
320
#if NCNN_VULKAN
321
        if (layer_vulkan)
322
        {
323
            if (vkdev)
324
            {
325
                int ret = layer_vulkan->load_param(pd);
326
                get_layer_properties();
327

328
                if (layer_vulkan->support_vulkan)
329
                    return ret;
330
            }
331

332
            // fallback to cpu layer
333
            delete layer_vulkan;
334
            layer_vulkan = 0;
335
        }
336
#endif // NCNN_VULKAN
337

338
        int ret = layer_cpu->load_param(pd);
339
        get_layer_properties();
340
        return ret;
341
    }
342

343
    virtual int load_model(const ModelBin& mb)
344
    {
345
#if NCNN_VULKAN
346
        if (layer_vulkan)
347
        {
348
            int ret = layer_vulkan->load_model(mb);
349
            get_layer_properties();
350
            return ret;
351
        }
352
#endif // NCNN_VULKAN
353

354
        int ret = layer_cpu->load_model(mb);
355
        get_layer_properties();
356
        return ret;
357
    }
358

359
    virtual int create_pipeline(const Option& opt)
360
    {
361
        set_layer_properties();
362
#if NCNN_VULKAN
363
        if (layer_vulkan)
364
        {
365
            if (vkdev)
366
            {
367
                int ret = layer_vulkan->create_pipeline(opt);
368
                get_layer_properties();
369
                return ret;
370
            }
371

372
            // fallback to cpu layer
373
            delete layer_vulkan;
374
            layer_vulkan = 0;
375
        }
376
#endif // NCNN_VULKAN
377

378
        int ret = layer_cpu->create_pipeline(opt);
379
        get_layer_properties();
380
        return ret;
381
    }
382

383
    virtual int destroy_pipeline(const Option& opt)
384
    {
385
#if NCNN_VULKAN
386
        if (layer_vulkan)
387
        {
388
            return layer_vulkan->destroy_pipeline(opt);
389
        }
390
#endif // NCNN_VULKAN
391

392
        return layer_cpu->destroy_pipeline(opt);
393
    }
394

395
public:
396
    virtual int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const
397
    {
398
        return layer_cpu->forward(bottom_blobs, top_blobs, opt);
399
    }
400

401
    virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const
402
    {
403
        return layer_cpu->forward(bottom_blob, top_blob, opt);
404
    }
405

406
    virtual int forward_inplace(std::vector<Mat>& bottom_top_blobs, const Option& opt) const
407
    {
408
        return layer_cpu->forward_inplace(bottom_top_blobs, opt);
409
    }
410

411
    virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const
412
    {
413
        return layer_cpu->forward_inplace(bottom_top_blob, opt);
414
    }
415

416
#if NCNN_VULKAN
417
public:
418
    virtual int upload_model(VkTransfer& cmd, const Option& opt)
419
    {
420
        return layer_vulkan ? layer_vulkan->upload_model(cmd, opt) : -1;
421
    }
422

423
    virtual int forward(const std::vector<VkMat>& bottom_blobs, std::vector<VkMat>& top_blobs, VkCompute& cmd, const Option& opt) const
424
    {
425
        return layer_vulkan ? layer_vulkan->forward(bottom_blobs, top_blobs, cmd, opt) : -1;
426
    }
427

428
    virtual int forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
429
    {
430
        return layer_vulkan ? layer_vulkan->forward(bottom_blob, top_blob, cmd, opt) : -1;
431
    }
432

433
    virtual int forward(const std::vector<VkImageMat>& bottom_blobs, std::vector<VkImageMat>& top_blobs, VkCompute& cmd, const Option& opt) const
434
    {
435
        return layer_vulkan ? layer_vulkan->forward(bottom_blobs, top_blobs, cmd, opt) : -1;
436
    }
437

438
    virtual int forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const
439
    {
440
        return layer_vulkan ? layer_vulkan->forward(bottom_blob, top_blob, cmd, opt) : -1;
441
    }
442

443
    virtual int forward_inplace(std::vector<VkMat>& bottom_top_blobs, VkCompute& cmd, const Option& opt) const
444
    {
445
        return layer_vulkan ? layer_vulkan->forward_inplace(bottom_top_blobs, cmd, opt) : -1;
446
    }
447

448
    virtual int forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const
449
    {
450
        return layer_vulkan ? layer_vulkan->forward_inplace(bottom_top_blob, cmd, opt) : -1;
451
    }
452

453
    virtual int forward_inplace(std::vector<VkImageMat>& bottom_top_blobs, VkCompute& cmd, const Option& opt) const
454
    {
455
        return layer_vulkan ? layer_vulkan->forward_inplace(bottom_top_blobs, cmd, opt) : -1;
456
    }
457

458
    virtual int forward_inplace(VkImageMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const
459
    {
460
        return layer_vulkan ? layer_vulkan->forward_inplace(bottom_top_blob, cmd, opt) : -1;
461
    }
462
#endif // NCNN_VULKAN
463
};
464

465
Layer* create_layer(int index)
466
{
467
    Layer* layer_cpu = create_layer_cpu(index);
468
    if (!layer_cpu)
469
        return 0;
470

471
    Layer_final* layer_final = new Layer_final;
472
    layer_final->layer_cpu = layer_cpu;
473

474
#if NCNN_VULKAN
475
    layer_final->layer_vulkan = create_layer_vulkan(index);
476
#endif
477

478
    layer_final->typeindex = index;
479
    layer_final->set_layer_properties();
480
    layer_final->get_layer_properties();
481

482
    return layer_final;
483
}
484

485
Layer* create_layer_naive(int index)
486
{
487
    if (index < 0 || index >= layer_registry_entry_count)
488
        return 0;
489

490
    layer_creator_func layer_creator = layer_registry[index].creator;
491
    if (!layer_creator)
492
        return 0;
493

494
    Layer* layer = layer_creator(0);
495
    layer->typeindex = index;
496
    return layer;
497
}
498

499
Layer* create_layer_cpu(int index)
500
{
501
    if (index < 0 || index >= layer_registry_entry_count)
502
        return 0;
503

504
    // clang-format off
505
    // *INDENT-OFF*
506
    layer_creator_func layer_creator = 0;
507
#if NCNN_RUNTIME_CPU && NCNN_AVX512
508
    if (ncnn::cpu_support_x86_avx512())
509
    {
510
        layer_creator = layer_registry_avx512[index].creator;
511
    }
512
    else
513
#endif// NCNN_RUNTIME_CPU && NCNN_AVX512
514
#if NCNN_RUNTIME_CPU && NCNN_FMA
515
    if (ncnn::cpu_support_x86_fma())
516
    {
517
        layer_creator = layer_registry_fma[index].creator;
518
    }
519
    else
520
#endif// NCNN_RUNTIME_CPU && NCNN_FMA
521
#if NCNN_RUNTIME_CPU && NCNN_AVX
522
    if (ncnn::cpu_support_x86_avx())
523
    {
524
        layer_creator = layer_registry_avx[index].creator;
525
    }
526
    else
527
#endif // NCNN_RUNTIME_CPU && NCNN_AVX
528
#if NCNN_RUNTIME_CPU && NCNN_LASX
529
    if (ncnn::cpu_support_loongarch_lasx())
530
    {
531
        layer_creator = layer_registry_lasx[index].creator;
532
    }
533
    else
534
#endif // NCNN_RUNTIME_CPU && NCNN_LASX
535
#if NCNN_RUNTIME_CPU && NCNN_LSX
536
    if (ncnn::cpu_support_loongarch_lsx())
537
    {
538
        layer_creator = layer_registry_lsx[index].creator;
539
    }
540
    else
541
#endif // NCNN_RUNTIME_CPU && NCNN_LSX
542
#if NCNN_RUNTIME_CPU && NCNN_MSA
543
    if (ncnn::cpu_support_mips_msa())
544
    {
545
        layer_creator = layer_registry_msa[index].creator;
546
    }
547
    else
548
#endif // NCNN_RUNTIME_CPU && NCNN_MSA
549
#if NCNN_RUNTIME_CPU && NCNN_RVV
550
    if (ncnn::cpu_support_riscv_v())
551
    {
552
        layer_creator = layer_registry_rvv[index].creator;
553
    }
554
    else
555
#endif // NCNN_RUNTIME_CPU && NCNN_RVV
556
    {
557
        layer_creator = layer_registry_arch[index].creator;
558
    }
559

560
    if (!layer_creator)
561
    {
562
        layer_creator = layer_registry[index].creator;
563
    }
564
    // *INDENT-ON*
565
    // clang-format on
566
    if (!layer_creator)
567
        return 0;
568

569
    Layer* layer = layer_creator(0);
570
    layer->typeindex = index;
571
    return layer;
572
}
573

574
#if NCNN_VULKAN
575
Layer* create_layer_vulkan(int index)
576
{
577
    if (index < 0 || index >= layer_registry_entry_count)
578
        return 0;
579

580
    layer_creator_func layer_creator = layer_registry_vulkan[index].creator;
581
    if (!layer_creator)
582
        return 0;
583

584
    Layer* layer = layer_creator(0);
585
    layer->typeindex = index;
586
    return layer;
587
}
588
#endif // NCNN_VULKAN
589

590
} // namespace ncnn
591

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.