ncnn

Форк
0
/
padding_vulkan.cpp 
1218 строк · 39.4 Кб
1
// Tencent is pleased to support the open source community by making ncnn available.
2
//
3
// Copyright (C) 2019 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 "padding_vulkan.h"
16

17
#include "layer_shader_type.h"
18

19
namespace ncnn {
20

21
Padding_vulkan::Padding_vulkan()
22
{
23
    support_vulkan = true;
24
    support_image_storage = true;
25

26
    pipeline_padding = 0;
27
    pipeline_padding_pack4 = 0;
28
    pipeline_padding_pack1to4 = 0;
29
    pipeline_padding_pack4to1 = 0;
30
    pipeline_padding_pack8 = 0;
31
    pipeline_padding_pack1to8 = 0;
32
    pipeline_padding_pack4to8 = 0;
33
    pipeline_padding_pack8to4 = 0;
34
    pipeline_padding_pack8to1 = 0;
35

36
    pipeline_padding_3d = 0;
37
    pipeline_padding_3d_pack4 = 0;
38
    pipeline_padding_3d_pack8 = 0;
39
}
40

41
int Padding_vulkan::create_pipeline(const Option& _opt)
42
{
43
    Option opt = _opt;
44
    const Mat& shape = bottom_shapes.empty() ? Mat() : bottom_shapes[0];
45
    const Mat& out_shape = top_shapes.empty() ? Mat() : top_shapes[0];
46

47
    int elempack = 1;
48
    if (shape.dims == 1) elempack = opt.use_shader_pack8 && shape.w % 8 == 0 ? 8 : shape.w % 4 == 0 ? 4 : 1;
49
    if (shape.dims == 2) elempack = opt.use_shader_pack8 && shape.h % 8 == 0 ? 8 : shape.h % 4 == 0 ? 4 : 1;
50
    if (shape.dims == 3 || shape.dims == 4) elempack = opt.use_shader_pack8 && shape.c % 8 == 0 ? 8 : shape.c % 4 == 0 ? 4 : 1;
51

52
    int out_elempack = 1;
53
    if (out_shape.dims == 1) out_elempack = opt.use_shader_pack8 && out_shape.w % 8 == 0 ? 8 : out_shape.w % 4 == 0 ? 4 : 1;
54
    if (out_shape.dims == 2) out_elempack = opt.use_shader_pack8 && out_shape.h % 8 == 0 ? 8 : out_shape.h % 4 == 0 ? 4 : 1;
55
    if (out_shape.dims == 3 || out_shape.dims == 4) out_elempack = opt.use_shader_pack8 && out_shape.c % 8 == 0 ? 8 : out_shape.c % 4 == 0 ? 4 : 1;
56

57
    int offset_elempack = 1;
58
    if (shape.dims == 1)
59
    {
60
        if (left == 0)
61
            offset_elempack = elempack;
62
        else
63
            offset_elempack = opt.use_shader_pack8 && left % 8 == 0 ? 8 : left % 4 == 0 ? 4 : 1;
64
    }
65
    else if (shape.dims == 2)
66
    {
67
        if (top == 0)
68
            offset_elempack = elempack;
69
        else
70
            offset_elempack = opt.use_shader_pack8 && top % 8 == 0 ? 8 : top % 4 == 0 ? 4 : 1;
71
    }
72
    else if (shape.dims == 3)
73
    {
74
        if (front == 0)
75
            offset_elempack = elempack;
76
        else
77
            offset_elempack = opt.use_shader_pack8 && front % 8 == 0 ? 8 : front % 4 == 0 ? 4 : 1;
78
    }
79
    else // if (shape.dims == 4)
80
    {
81
        offset_elempack = elempack;
82
    }
83

84
    offset_elempack = std::min(offset_elempack, elempack);
85

86
    size_t elemsize;
87
    size_t out_elemsize;
88
    if (opt.use_fp16_storage)
89
    {
90
        elemsize = elempack * 2u;
91
        out_elemsize = out_elempack * 2u;
92
    }
93
    else if (opt.use_fp16_packed)
94
    {
95
        elemsize = elempack == 1 ? 4u : elempack * 2u;
96
        out_elemsize = out_elempack == 1 ? 4u : out_elempack * 2u;
97
    }
98
    else
99
    {
100
        elemsize = elempack * 4u;
101
        out_elemsize = out_elempack * 4u;
102
    }
103

104
    Mat shape_packed;
105
    if (shape.dims == 1) shape_packed = Mat(shape.w / elempack, (void*)0, elemsize, elempack);
106
    if (shape.dims == 2) shape_packed = Mat(shape.w, shape.h / elempack, (void*)0, elemsize, elempack);
107
    if (shape.dims == 3) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack);
108
    if (shape.dims == 4) shape_packed = Mat(shape.w, shape.h, shape.d, shape.c / elempack, (void*)0, elemsize, elempack);
109

110
    Mat out_shape_packed;
111
    if (out_shape.dims == 1) out_shape_packed = Mat(out_shape.w / out_elempack, (void*)0, out_elemsize, out_elempack);
112
    if (out_shape.dims == 2) out_shape_packed = Mat(out_shape.w, out_shape.h / out_elempack, (void*)0, out_elemsize, out_elempack);
113
    if (out_shape.dims == 3) out_shape_packed = Mat(out_shape.w, out_shape.h, out_shape.c / out_elempack, (void*)0, out_elemsize, out_elempack);
114
    if (out_shape.dims == 4) out_shape_packed = Mat(out_shape.w, out_shape.h, out_shape.d, out_shape.c / out_elempack, (void*)0, out_elemsize, out_elempack);
115

116
    Mat shape_unpacked = shape_packed;
117
    if (one_blob_only && shape.dims != 0 && elempack > offset_elempack)
118
    {
119
        size_t offset_elemsize;
120
        if (opt.use_fp16_storage)
121
        {
122
            offset_elemsize = offset_elempack * 2u;
123
        }
124
        else if (opt.use_fp16_packed)
125
        {
126
            offset_elemsize = offset_elempack == 1 ? 4u : offset_elempack * 2u;
127
        }
128
        else
129
        {
130
            offset_elemsize = offset_elempack * 4u;
131
        }
132

133
        if (shape.dims == 1) shape_unpacked = Mat(shape.w / offset_elempack, (void*)0, offset_elemsize, offset_elempack);
134
        if (shape.dims == 2) shape_unpacked = Mat(shape.w, shape.h / offset_elempack, (void*)0, offset_elemsize, offset_elempack);
135
        if (shape.dims == 3) shape_unpacked = Mat(shape.w, shape.h, shape.c / offset_elempack, (void*)0, offset_elemsize, offset_elempack);
136
        // if (shape.dims == 4) should never reach here
137
    }
138

139
    // check blob shape
140
    if (!vkdev->shape_support_image_storage(shape_packed) || !vkdev->shape_support_image_storage(shape_unpacked) || !vkdev->shape_support_image_storage(out_shape_packed))
141
    {
142
        support_image_storage = false;
143
        opt.use_image_storage = false;
144
    }
145

146
    std::vector<vk_specialization_type> specializations(3 + 10);
147
    specializations[0].i = type;
148
    specializations[1].f = value;
149
    specializations[2].i = per_channel_pad_data_size ? 1 : 0;
150
    specializations[3 + 0].i = shape_unpacked.dims;
151
    specializations[3 + 1].i = shape_unpacked.w;
152
    specializations[3 + 2].i = shape_unpacked.h;
153
    specializations[3 + 3].i = shape_unpacked.c;
154
    specializations[3 + 4].i = shape_unpacked.cstep;
155
    specializations[3 + 5].i = out_shape_packed.dims;
156
    specializations[3 + 6].i = out_shape_packed.w;
157
    specializations[3 + 7].i = out_shape_packed.h;
158
    specializations[3 + 8].i = out_shape_packed.c;
159
    specializations[3 + 9].i = out_shape_packed.cstep;
160

161
    std::vector<vk_specialization_type> specializations_3d(3 + 12);
162
    specializations_3d[0].i = type;
163
    specializations_3d[1].f = value;
164
    specializations_3d[2].i = per_channel_pad_data_size ? 1 : 0;
165
    specializations_3d[3 + 0].i = shape_unpacked.dims;
166
    specializations_3d[3 + 1].i = shape_unpacked.w;
167
    specializations_3d[3 + 2].i = shape_unpacked.h;
168
    specializations_3d[3 + 3].i = shape_unpacked.d;
169
    specializations_3d[3 + 4].i = shape_unpacked.c;
170
    specializations_3d[3 + 5].i = shape_unpacked.cstep;
171
    specializations_3d[3 + 6].i = out_shape_packed.dims;
172
    specializations_3d[3 + 7].i = out_shape_packed.w;
173
    specializations_3d[3 + 8].i = out_shape_packed.h;
174
    specializations_3d[3 + 9].i = out_shape_packed.d;
175
    specializations_3d[3 + 10].i = out_shape_packed.c;
176
    specializations_3d[3 + 11].i = out_shape_packed.cstep;
177

178
    Mat local_size_xyz;
179
    if (out_shape_packed.dims == 1)
180
    {
181
        local_size_xyz.w = std::min(64, out_shape_packed.w);
182
        local_size_xyz.h = 1;
183
        local_size_xyz.c = 1;
184
    }
185
    if (out_shape_packed.dims == 2)
186
    {
187
        local_size_xyz.w = std::min(8, out_shape_packed.w);
188
        local_size_xyz.h = std::min(8, out_shape_packed.h);
189
        local_size_xyz.c = 1;
190
    }
191
    if (out_shape_packed.dims == 3)
192
    {
193
        local_size_xyz.w = std::min(4, out_shape_packed.w);
194
        local_size_xyz.h = std::min(4, out_shape_packed.h);
195
        local_size_xyz.c = std::min(4, out_shape_packed.c);
196
    }
197
    if (out_shape_packed.dims == 4)
198
    {
199
        local_size_xyz.w = std::min(4, out_shape_packed.w);
200
        local_size_xyz.h = std::min(4, out_shape_packed.h * out_shape_packed.d);
201
        local_size_xyz.c = std::min(4, out_shape_packed.c);
202
    }
203

204
    // pack1
205
    if (out_shape.dims == 0 || (offset_elempack == 1 && out_elempack == 1))
206
    {
207
        pipeline_padding = new Pipeline(vkdev);
208
        pipeline_padding->set_optimal_local_size_xyz(local_size_xyz);
209
        pipeline_padding->create(LayerShaderType::padding, opt, specializations);
210

211
        pipeline_padding_3d = new Pipeline(vkdev);
212
        pipeline_padding_3d->set_optimal_local_size_xyz(local_size_xyz);
213
        pipeline_padding_3d->create(LayerShaderType::padding_3d, opt, specializations_3d);
214
    }
215

216
    // pack4
217
    if (out_shape.dims == 0 || (offset_elempack == 4 && out_elempack == 4))
218
    {
219
        pipeline_padding_pack4 = new Pipeline(vkdev);
220
        pipeline_padding_pack4->set_optimal_local_size_xyz(local_size_xyz);
221
        pipeline_padding_pack4->create(LayerShaderType::padding_pack4, opt, specializations);
222

223
        pipeline_padding_3d_pack4 = new Pipeline(vkdev);
224
        pipeline_padding_3d_pack4->set_optimal_local_size_xyz(local_size_xyz);
225
        pipeline_padding_3d_pack4->create(LayerShaderType::padding_3d_pack4, opt, specializations_3d);
226
    }
227

228
    // pack1to4
229
    if (out_shape.dims == 0 || (offset_elempack == 1 && out_elempack == 4))
230
    {
231
        pipeline_padding_pack1to4 = new Pipeline(vkdev);
232
        pipeline_padding_pack1to4->set_optimal_local_size_xyz(local_size_xyz);
233
        pipeline_padding_pack1to4->create(LayerShaderType::padding_pack1to4, opt, specializations);
234
    }
235

236
    // pack4to1
237
    if (out_shape.dims == 0 || (offset_elempack == 4 && out_elempack == 1))
238
    {
239
        pipeline_padding_pack4to1 = new Pipeline(vkdev);
240
        pipeline_padding_pack4to1->set_optimal_local_size_xyz(local_size_xyz);
241
        pipeline_padding_pack4to1->create(LayerShaderType::padding_pack4to1, opt, specializations);
242
    }
243

244
    // pack8
245
    if ((opt.use_shader_pack8 && out_shape.dims == 0) || (offset_elempack == 8 && out_elempack == 8))
246
    {
247
        pipeline_padding_pack8 = new Pipeline(vkdev);
248
        pipeline_padding_pack8->set_optimal_local_size_xyz(local_size_xyz);
249
        pipeline_padding_pack8->create(LayerShaderType::padding_pack8, opt, specializations);
250

251
        pipeline_padding_3d_pack8 = new Pipeline(vkdev);
252
        pipeline_padding_3d_pack8->set_optimal_local_size_xyz(local_size_xyz);
253
        pipeline_padding_3d_pack8->create(LayerShaderType::padding_3d_pack8, opt, specializations_3d);
254
    }
255

256
    // pack1to8
257
    if ((opt.use_shader_pack8 && out_shape.dims == 0) || (offset_elempack == 1 && out_elempack == 8))
258
    {
259
        pipeline_padding_pack1to8 = new Pipeline(vkdev);
260
        pipeline_padding_pack1to8->set_optimal_local_size_xyz(local_size_xyz);
261
        pipeline_padding_pack1to8->create(LayerShaderType::padding_pack1to8, opt, specializations);
262
    }
263

264
    // pack4to8
265
    if ((opt.use_shader_pack8 && out_shape.dims == 0) || (offset_elempack == 4 && out_elempack == 8))
266
    {
267
        pipeline_padding_pack4to8 = new Pipeline(vkdev);
268
        pipeline_padding_pack4to8->set_optimal_local_size_xyz(local_size_xyz);
269
        pipeline_padding_pack4to8->create(LayerShaderType::padding_pack4to8, opt, specializations);
270
    }
271

272
    // pack8to4
273
    if ((opt.use_shader_pack8 && out_shape.dims == 0) || (offset_elempack == 8 && out_elempack == 4))
274
    {
275
        pipeline_padding_pack8to4 = new Pipeline(vkdev);
276
        pipeline_padding_pack8to4->set_optimal_local_size_xyz(local_size_xyz);
277
        pipeline_padding_pack8to4->create(LayerShaderType::padding_pack8to4, opt, specializations);
278
    }
279

280
    // pack8to1
281
    if ((opt.use_shader_pack8 && out_shape.dims == 0) || (offset_elempack == 8 && out_elempack == 1))
282
    {
283
        pipeline_padding_pack8to1 = new Pipeline(vkdev);
284
        pipeline_padding_pack8to1->set_optimal_local_size_xyz(local_size_xyz);
285
        pipeline_padding_pack8to1->create(LayerShaderType::padding_pack8to1, opt, specializations);
286
    }
287

288
    return 0;
289
}
290

291
int Padding_vulkan::destroy_pipeline(const Option& /*opt*/)
292
{
293
    delete pipeline_padding;
294
    pipeline_padding = 0;
295

296
    delete pipeline_padding_pack4;
297
    pipeline_padding_pack4 = 0;
298

299
    delete pipeline_padding_pack1to4;
300
    pipeline_padding_pack1to4 = 0;
301

302
    delete pipeline_padding_pack4to1;
303
    pipeline_padding_pack4to1 = 0;
304

305
    delete pipeline_padding_pack8;
306
    pipeline_padding_pack8 = 0;
307

308
    delete pipeline_padding_pack1to8;
309
    pipeline_padding_pack1to8 = 0;
310

311
    delete pipeline_padding_pack4to8;
312
    pipeline_padding_pack4to8 = 0;
313

314
    delete pipeline_padding_pack8to4;
315
    pipeline_padding_pack8to4 = 0;
316

317
    delete pipeline_padding_pack8to1;
318
    pipeline_padding_pack8to1 = 0;
319

320
    delete pipeline_padding_3d;
321
    pipeline_padding_3d = 0;
322

323
    delete pipeline_padding_3d_pack4;
324
    pipeline_padding_3d_pack4 = 0;
325

326
    delete pipeline_padding_3d_pack8;
327
    pipeline_padding_3d_pack8 = 0;
328

329
    return 0;
330
}
331

332
int Padding_vulkan::upload_model(VkTransfer& cmd, const Option& opt)
333
{
334
    if (per_channel_pad_data_size == 0)
335
        return 0;
336

337
    int elempack = opt.use_shader_pack8 && per_channel_pad_data_size % 8 == 0 ? 8 : per_channel_pad_data_size % 4 == 0 ? 4 : 1;
338

339
    Mat per_channel_pad_data_packed;
340
    convert_packing(per_channel_pad_data, per_channel_pad_data_packed, elempack, opt);
341

342
    if (support_image_storage && opt.use_image_storage)
343
    {
344
        cmd.record_upload(per_channel_pad_data_packed, per_channel_pad_data_gpu_image, opt);
345
    }
346
    else
347
    {
348
        cmd.record_upload(per_channel_pad_data_packed, per_channel_pad_data_gpu, opt);
349
    }
350

351
    if (opt.lightmode)
352
    {
353
        per_channel_pad_data.release();
354
    }
355

356
    return 0;
357
}
358

359
int Padding_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
360
{
361
    int dims = bottom_blob.dims;
362
    int w = bottom_blob.w;
363
    int h = bottom_blob.h;
364
    int d = bottom_blob.d;
365
    int channels = bottom_blob.c;
366
    size_t elemsize = bottom_blob.elemsize;
367
    int elempack = bottom_blob.elempack;
368

369
    int outw = 0;
370
    int outh = 0;
371
    int outd = 0;
372
    int outc = 0;
373

374
    int offset_elempack;
375
    int out_elempack;
376

377
    if (dims == 1)
378
    {
379
        if (left == 0 && right == 0)
380
        {
381
            top_blob = bottom_blob;
382
            return 0;
383
        }
384

385
        outw = w * elempack + left + right;
386
        out_elempack = opt.use_shader_pack8 && outw % 8 == 0 ? 8 : outw % 4 == 0 ? 4 : 1;
387
        offset_elempack = left == 0 ? elempack : opt.use_shader_pack8 && left % 8 == 0 ? 8 : left % 4 == 0 ? 4 : 1;
388
    }
389
    else if (dims == 2)
390
    {
391
        if (top == 0 && bottom == 0 && left == 0 && right == 0)
392
        {
393
            top_blob = bottom_blob;
394
            return 0;
395
        }
396

397
        outw = w + left + right;
398
        outh = h * elempack + top + bottom;
399
        out_elempack = opt.use_shader_pack8 && outh % 8 == 0 ? 8 : outh % 4 == 0 ? 4 : 1;
400
        offset_elempack = top == 0 ? elempack : opt.use_shader_pack8 && top % 8 == 0 ? 8 : top % 4 == 0 ? 4 : 1;
401
    }
402
    else if (dims == 3)
403
    {
404
        if (top == 0 && bottom == 0 && left == 0 && right == 0 && front == 0 && behind == 0)
405
        {
406
            top_blob = bottom_blob;
407
            return 0;
408
        }
409

410
        outw = w + left + right;
411
        outh = h + top + bottom;
412
        outc = channels * elempack + front + behind;
413
        out_elempack = opt.use_shader_pack8 && outc % 8 == 0 ? 8 : outc % 4 == 0 ? 4 : 1;
414
        offset_elempack = front == 0 ? elempack : opt.use_shader_pack8 && front % 8 == 0 ? 8 : front % 4 == 0 ? 4 : 1;
415
    }
416
    else // if (dims == 4)
417
    {
418
        if (top == 0 && bottom == 0 && left == 0 && right == 0 && front == 0 && behind == 0)
419
        {
420
            top_blob = bottom_blob;
421
            return 0;
422
        }
423

424
        outw = w + left + right;
425
        outh = h + top + bottom;
426
        outd = d + front + behind;
427
        outc = channels * elempack;
428
        out_elempack = elempack;
429
        offset_elempack = elempack;
430
    }
431

432
    offset_elempack = std::min(offset_elempack, elempack);
433

434
    size_t out_elemsize = elemsize / elempack * out_elempack;
435

436
    if (opt.use_fp16_packed && !opt.use_fp16_storage)
437
    {
438
        if (out_elempack == 8) out_elemsize = 8 * 2u;
439
        if (out_elempack == 4) out_elemsize = 4 * 2u;
440
        if (out_elempack == 1) out_elemsize = 4u;
441
    }
442

443
    // unpacking
444
    VkMat bottom_blob_unpacked = bottom_blob;
445
    if (elempack > offset_elempack)
446
    {
447
        Option opt_pack1 = opt;
448
        opt_pack1.blob_vkallocator = opt.workspace_vkallocator;
449

450
        vkdev->convert_packing(bottom_blob, bottom_blob_unpacked, offset_elempack, cmd, opt_pack1);
451
    }
452

453
    if (dims == 1)
454
    {
455
        top_blob.create(outw / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
456
    }
457
    else if (dims == 2)
458
    {
459
        top_blob.create(outw, outh / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
460
    }
461
    else if (dims == 3)
462
    {
463
        top_blob.create(outw, outh, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
464
    }
465
    else // if (dims == 4)
466
    {
467
        top_blob.create(outw, outh, outd, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
468
    }
469
    if (top_blob.empty())
470
        return -100;
471

472
    std::vector<VkMat> bindings(3);
473
    bindings[0] = bottom_blob_unpacked;
474
    bindings[1] = top_blob;
475
    bindings[2] = per_channel_pad_data_gpu;
476

477
    if (dims == 4)
478
    {
479
        std::vector<vk_constant_type> constants(15);
480
        constants[0].i = bottom_blob_unpacked.dims;
481
        constants[1].i = bottom_blob_unpacked.w;
482
        constants[2].i = bottom_blob_unpacked.h;
483
        constants[3].i = bottom_blob_unpacked.d;
484
        constants[4].i = bottom_blob_unpacked.c;
485
        constants[5].i = bottom_blob_unpacked.cstep;
486
        constants[6].i = top_blob.dims;
487
        constants[7].i = top_blob.w;
488
        constants[8].i = top_blob.h;
489
        constants[9].i = top_blob.d;
490
        constants[10].i = top_blob.c;
491
        constants[11].i = top_blob.cstep;
492
        constants[12].i = left;
493
        constants[13].i = top;
494
        constants[14].i = front;
495

496
        const Pipeline* pipeline = out_elempack == 8 ? pipeline_padding_3d_pack8
497
                                   : out_elempack == 4 ? pipeline_padding_3d_pack4
498
                                   : pipeline_padding_3d;
499

500
        cmd.record_pipeline(pipeline, bindings, constants, top_blob);
501

502
        return 0;
503
    }
504

505
    std::vector<vk_constant_type> constants(13);
506
    constants[0].i = bottom_blob_unpacked.dims;
507
    constants[1].i = bottom_blob_unpacked.w;
508
    constants[2].i = bottom_blob_unpacked.h;
509
    constants[3].i = bottom_blob_unpacked.c;
510
    constants[4].i = bottom_blob_unpacked.cstep;
511
    constants[5].i = top_blob.dims;
512
    constants[6].i = top_blob.w;
513
    constants[7].i = top_blob.h;
514
    constants[8].i = top_blob.c;
515
    constants[9].i = top_blob.cstep;
516
    constants[10].i = left;
517
    constants[11].i = top;
518
    constants[12].i = front;
519

520
    const Pipeline* pipeline = 0;
521
    if (offset_elempack == 1 && out_elempack == 1)
522
    {
523
        pipeline = pipeline_padding;
524
    }
525
    else if (offset_elempack == 4 && out_elempack == 4)
526
    {
527
        pipeline = pipeline_padding_pack4;
528
    }
529
    else if (offset_elempack == 1 && out_elempack == 4)
530
    {
531
        pipeline = pipeline_padding_pack1to4;
532
    }
533
    else if (offset_elempack == 4 && out_elempack == 1)
534
    {
535
        pipeline = pipeline_padding_pack4to1;
536
    }
537
    else if (offset_elempack == 8 && out_elempack == 8)
538
    {
539
        pipeline = pipeline_padding_pack8;
540
    }
541
    else if (offset_elempack == 1 && out_elempack == 8)
542
    {
543
        pipeline = pipeline_padding_pack1to8;
544
    }
545
    else if (offset_elempack == 4 && out_elempack == 8)
546
    {
547
        pipeline = pipeline_padding_pack4to8;
548
    }
549
    else if (offset_elempack == 8 && out_elempack == 4)
550
    {
551
        pipeline = pipeline_padding_pack8to4;
552
    }
553
    else if (offset_elempack == 8 && out_elempack == 1)
554
    {
555
        pipeline = pipeline_padding_pack8to1;
556
    }
557

558
    cmd.record_pipeline(pipeline, bindings, constants, top_blob);
559

560
    return 0;
561
}
562

563
int Padding_vulkan::forward(const std::vector<VkMat>& bottom_blobs, std::vector<VkMat>& top_blobs, VkCompute& cmd, const Option& opt) const
564
{
565
    const VkMat& bottom_blob = bottom_blobs[0];
566
    const VkMat& reference_blob = bottom_blobs[1];
567

568
    VkMat& top_blob = top_blobs[0];
569
    int _top;
570
    int _bottom;
571
    int _left;
572
    int _right;
573
    int _front;
574
    int _behind;
575
    {
576
        const int* param_data = reference_blob.mapped();
577

578
        _top = param_data[0];
579
        _bottom = param_data[1];
580
        _left = param_data[2];
581
        _right = param_data[3];
582
        _front = param_data[4];
583
        _behind = param_data[5];
584
    }
585

586
    int dims = bottom_blob.dims;
587
    int w = bottom_blob.w;
588
    int h = bottom_blob.h;
589
    int d = bottom_blob.d;
590
    int channels = bottom_blob.c;
591
    size_t elemsize = bottom_blob.elemsize;
592
    int elempack = bottom_blob.elempack;
593

594
    int outw = 0;
595
    int outh = 0;
596
    int outd = 0;
597
    int outc = 0;
598

599
    int offset_elempack;
600
    int out_elempack;
601

602
    if (dims == 1)
603
    {
604
        if (_left == 0 && _right == 0)
605
        {
606
            top_blob = bottom_blob;
607
            return 0;
608
        }
609

610
        outw = w * elempack + _left + _right;
611
        out_elempack = opt.use_shader_pack8 && outw % 8 == 0 ? 8 : outw % 4 == 0 ? 4 : 1;
612
        offset_elempack = _left == 0 ? elempack : opt.use_shader_pack8 && _left % 8 == 0 ? 8 : _left % 4 == 0 ? 4 : 1;
613
    }
614
    else if (dims == 2)
615
    {
616
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0)
617
        {
618
            top_blob = bottom_blob;
619
            return 0;
620
        }
621

622
        outw = w + _left + _right;
623
        outh = h * elempack + _top + _bottom;
624
        out_elempack = opt.use_shader_pack8 && outh % 8 == 0 ? 8 : outh % 4 == 0 ? 4 : 1;
625
        offset_elempack = _top == 0 ? elempack : opt.use_shader_pack8 && _top % 8 == 0 ? 8 : _top % 4 == 0 ? 4 : 1;
626
    }
627
    else if (dims == 3)
628
    {
629
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0 && _front == 0 && _behind == 0)
630
        {
631
            top_blob = bottom_blob;
632
            return 0;
633
        }
634

635
        outw = w + _left + _right;
636
        outh = h + _top + _bottom;
637
        outc = channels * elempack + _front + _behind;
638
        out_elempack = opt.use_shader_pack8 && outc % 8 == 0 ? 8 : outc % 4 == 0 ? 4 : 1;
639
        offset_elempack = _front == 0 ? elempack : opt.use_shader_pack8 && _front % 8 == 0 ? 8 : _front % 4 == 0 ? 4 : 1;
640
    }
641
    else // if (dims == 4)
642
    {
643
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0 && _front == 0 && _behind == 0)
644
        {
645
            top_blob = bottom_blob;
646
            return 0;
647
        }
648

649
        outw = w + _left + _right;
650
        outh = h + _top + _bottom;
651
        outd = d + _front + _behind;
652
        outc = channels * elempack;
653
        out_elempack = elempack;
654
        offset_elempack = elempack;
655
    }
656

657
    offset_elempack = std::min(offset_elempack, elempack);
658

659
    size_t out_elemsize = elemsize / elempack * out_elempack;
660

661
    if (opt.use_fp16_packed && !opt.use_fp16_storage)
662
    {
663
        if (out_elempack == 8) out_elemsize = 8 * 2u;
664
        if (out_elempack == 4) out_elemsize = 4 * 2u;
665
        if (out_elempack == 1) out_elemsize = 4u;
666
    }
667

668
    // unpacking
669
    VkMat bottom_blob_unpacked = bottom_blob;
670
    if (elempack > offset_elempack)
671
    {
672
        Option opt_pack1 = opt;
673
        opt_pack1.blob_vkallocator = opt.workspace_vkallocator;
674

675
        vkdev->convert_packing(bottom_blob, bottom_blob_unpacked, offset_elempack, cmd, opt_pack1);
676
    }
677

678
    if (dims == 1)
679
    {
680
        top_blob.create(outw / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
681
    }
682
    else if (dims == 2)
683
    {
684
        top_blob.create(outw, outh / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
685
    }
686
    else if (dims == 3)
687
    {
688
        top_blob.create(outw, outh, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
689
    }
690
    else // if (dims == 4)
691
    {
692
        top_blob.create(outw, outh, outd, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
693
    }
694
    if (top_blob.empty())
695
        return -100;
696

697
    std::vector<VkMat> bindings(3);
698
    bindings[0] = bottom_blob_unpacked;
699
    bindings[1] = top_blob;
700
    bindings[2] = per_channel_pad_data_gpu;
701

702
    if (dims == 4)
703
    {
704
        std::vector<vk_constant_type> constants(15);
705
        constants[0].i = bottom_blob_unpacked.dims;
706
        constants[1].i = bottom_blob_unpacked.w;
707
        constants[2].i = bottom_blob_unpacked.h;
708
        constants[3].i = bottom_blob_unpacked.d;
709
        constants[4].i = bottom_blob_unpacked.c;
710
        constants[5].i = bottom_blob_unpacked.cstep;
711
        constants[6].i = top_blob.dims;
712
        constants[7].i = top_blob.w;
713
        constants[8].i = top_blob.h;
714
        constants[9].i = top_blob.d;
715
        constants[10].i = top_blob.c;
716
        constants[11].i = top_blob.cstep;
717
        constants[12].i = _left;
718
        constants[13].i = _top;
719
        constants[14].i = _front;
720

721
        const Pipeline* pipeline = out_elempack == 8 ? pipeline_padding_3d_pack8
722
                                   : out_elempack == 4 ? pipeline_padding_3d_pack4
723
                                   : pipeline_padding_3d;
724

725
        cmd.record_pipeline(pipeline, bindings, constants, top_blob);
726

727
        return 0;
728
    }
729

730
    std::vector<vk_constant_type> constants(13);
731
    constants[0].i = bottom_blob_unpacked.dims;
732
    constants[1].i = bottom_blob_unpacked.w;
733
    constants[2].i = bottom_blob_unpacked.h;
734
    constants[3].i = bottom_blob_unpacked.c;
735
    constants[4].i = bottom_blob_unpacked.cstep;
736
    constants[5].i = top_blob.dims;
737
    constants[6].i = top_blob.w;
738
    constants[7].i = top_blob.h;
739
    constants[8].i = top_blob.c;
740
    constants[9].i = top_blob.cstep;
741
    constants[10].i = _left;
742
    constants[11].i = _top;
743
    constants[12].i = _front;
744

745
    const Pipeline* pipeline = 0;
746
    if (offset_elempack == 1 && out_elempack == 1)
747
    {
748
        pipeline = pipeline_padding;
749
    }
750
    else if (offset_elempack == 4 && out_elempack == 4)
751
    {
752
        pipeline = pipeline_padding_pack4;
753
    }
754
    else if (offset_elempack == 1 && out_elempack == 4)
755
    {
756
        pipeline = pipeline_padding_pack1to4;
757
    }
758
    else if (offset_elempack == 4 && out_elempack == 1)
759
    {
760
        pipeline = pipeline_padding_pack4to1;
761
    }
762
    else if (offset_elempack == 8 && out_elempack == 8)
763
    {
764
        pipeline = pipeline_padding_pack8;
765
    }
766
    else if (offset_elempack == 1 && out_elempack == 8)
767
    {
768
        pipeline = pipeline_padding_pack1to8;
769
    }
770
    else if (offset_elempack == 4 && out_elempack == 8)
771
    {
772
        pipeline = pipeline_padding_pack4to8;
773
    }
774
    else if (offset_elempack == 8 && out_elempack == 4)
775
    {
776
        pipeline = pipeline_padding_pack8to4;
777
    }
778
    else if (offset_elempack == 8 && out_elempack == 1)
779
    {
780
        pipeline = pipeline_padding_pack8to1;
781
    }
782

783
    cmd.record_pipeline(pipeline, bindings, constants, top_blob);
784

785
    return 0;
786
}
787

788
int Padding_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const
789
{
790
    int dims = bottom_blob.dims;
791
    int w = bottom_blob.w;
792
    int h = bottom_blob.h;
793
    int d = bottom_blob.d;
794
    int channels = bottom_blob.c;
795
    size_t elemsize = bottom_blob.elemsize;
796
    int elempack = bottom_blob.elempack;
797

798
    int outw = 0;
799
    int outh = 0;
800
    int outd = 0;
801
    int outc = 0;
802

803
    int offset_elempack;
804
    int out_elempack;
805

806
    if (dims == 1)
807
    {
808
        if (left == 0 && right == 0)
809
        {
810
            top_blob = bottom_blob;
811
            return 0;
812
        }
813

814
        outw = w * elempack + left + right;
815
        out_elempack = opt.use_shader_pack8 && outw % 8 == 0 ? 8 : outw % 4 == 0 ? 4 : 1;
816
        offset_elempack = left == 0 ? elempack : opt.use_shader_pack8 && left % 8 == 0 ? 8 : left % 4 == 0 ? 4 : 1;
817
    }
818
    else if (dims == 2)
819
    {
820
        if (top == 0 && bottom == 0 && left == 0 && right == 0)
821
        {
822
            top_blob = bottom_blob;
823
            return 0;
824
        }
825

826
        outw = w + left + right;
827
        outh = h * elempack + top + bottom;
828
        out_elempack = opt.use_shader_pack8 && outh % 8 == 0 ? 8 : outh % 4 == 0 ? 4 : 1;
829
        offset_elempack = top == 0 ? elempack : opt.use_shader_pack8 && top % 8 == 0 ? 8 : top % 4 == 0 ? 4 : 1;
830
    }
831
    else if (dims == 3)
832
    {
833
        if (top == 0 && bottom == 0 && left == 0 && right == 0 && front == 0 && behind == 0)
834
        {
835
            top_blob = bottom_blob;
836
            return 0;
837
        }
838

839
        outw = w + left + right;
840
        outh = h + top + bottom;
841
        outc = channels * elempack + front + behind;
842
        out_elempack = opt.use_shader_pack8 && outc % 8 == 0 ? 8 : outc % 4 == 0 ? 4 : 1;
843
        offset_elempack = front == 0 ? elempack : opt.use_shader_pack8 && front % 8 == 0 ? 8 : front % 4 == 0 ? 4 : 1;
844
    }
845
    else // if (dims == 4)
846
    {
847
        if (top == 0 && bottom == 0 && left == 0 && right == 0 && front == 0 && behind == 0)
848
        {
849
            top_blob = bottom_blob;
850
            return 0;
851
        }
852

853
        outw = w + left + right;
854
        outh = h + top + bottom;
855
        outd = d + front + behind;
856
        outc = channels * elempack;
857
        out_elempack = elempack;
858
        offset_elempack = elempack;
859
    }
860

861
    offset_elempack = std::min(offset_elempack, elempack);
862

863
    size_t out_elemsize = elemsize / elempack * out_elempack;
864

865
    if (opt.use_fp16_packed && !opt.use_fp16_storage)
866
    {
867
        if (out_elempack == 8) out_elemsize = 8 * 2u;
868
        if (out_elempack == 4) out_elemsize = 4 * 2u;
869
        if (out_elempack == 1) out_elemsize = 4u;
870
    }
871

872
    // unpacking
873
    VkImageMat bottom_blob_unpacked = bottom_blob;
874
    if (elempack > offset_elempack)
875
    {
876
        Option opt_pack1 = opt;
877
        opt_pack1.blob_vkallocator = opt.workspace_vkallocator;
878

879
        vkdev->convert_packing(bottom_blob, bottom_blob_unpacked, offset_elempack, cmd, opt_pack1);
880
    }
881

882
    if (dims == 1)
883
    {
884
        top_blob.create(outw / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
885
    }
886
    else if (dims == 2)
887
    {
888
        top_blob.create(outw, outh / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
889
    }
890
    else if (dims == 3)
891
    {
892
        top_blob.create(outw, outh, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
893
    }
894
    else // if (dims == 4)
895
    {
896
        top_blob.create(outw, outh, outd, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
897
    }
898
    if (top_blob.empty())
899
        return -100;
900

901
    std::vector<VkImageMat> bindings(3);
902
    bindings[0] = bottom_blob_unpacked;
903
    bindings[1] = top_blob;
904
    bindings[2] = per_channel_pad_data_gpu_image;
905

906
    if (dims == 4)
907
    {
908
        std::vector<vk_constant_type> constants(15);
909
        constants[0].i = bottom_blob_unpacked.dims;
910
        constants[1].i = bottom_blob_unpacked.w;
911
        constants[2].i = bottom_blob_unpacked.h;
912
        constants[3].i = bottom_blob_unpacked.d;
913
        constants[4].i = bottom_blob_unpacked.c;
914
        constants[5].i = 0;
915
        constants[6].i = top_blob.dims;
916
        constants[7].i = top_blob.w;
917
        constants[8].i = top_blob.h;
918
        constants[9].i = top_blob.d;
919
        constants[10].i = top_blob.c;
920
        constants[11].i = 0;
921
        constants[12].i = left;
922
        constants[13].i = top;
923
        constants[14].i = front;
924

925
        const Pipeline* pipeline = out_elempack == 8 ? pipeline_padding_3d_pack8
926
                                   : out_elempack == 4 ? pipeline_padding_3d_pack4
927
                                   : pipeline_padding_3d;
928

929
        cmd.record_pipeline(pipeline, bindings, constants, top_blob);
930

931
        return 0;
932
    }
933

934
    std::vector<vk_constant_type> constants(13);
935
    constants[0].i = bottom_blob_unpacked.dims;
936
    constants[1].i = bottom_blob_unpacked.w;
937
    constants[2].i = bottom_blob_unpacked.h;
938
    constants[3].i = bottom_blob_unpacked.c;
939
    constants[4].i = 0;
940
    constants[5].i = top_blob.dims;
941
    constants[6].i = top_blob.w;
942
    constants[7].i = top_blob.h;
943
    constants[8].i = top_blob.c;
944
    constants[9].i = 0;
945
    constants[10].i = left;
946
    constants[11].i = top;
947
    constants[12].i = front;
948

949
    const Pipeline* pipeline = 0;
950
    if (offset_elempack == 1 && out_elempack == 1)
951
    {
952
        pipeline = pipeline_padding;
953
    }
954
    else if (offset_elempack == 4 && out_elempack == 4)
955
    {
956
        pipeline = pipeline_padding_pack4;
957
    }
958
    else if (offset_elempack == 1 && out_elempack == 4)
959
    {
960
        pipeline = pipeline_padding_pack1to4;
961
    }
962
    else if (offset_elempack == 4 && out_elempack == 1)
963
    {
964
        pipeline = pipeline_padding_pack4to1;
965
    }
966
    else if (offset_elempack == 8 && out_elempack == 8)
967
    {
968
        pipeline = pipeline_padding_pack8;
969
    }
970
    else if (offset_elempack == 1 && out_elempack == 8)
971
    {
972
        pipeline = pipeline_padding_pack1to8;
973
    }
974
    else if (offset_elempack == 4 && out_elempack == 8)
975
    {
976
        pipeline = pipeline_padding_pack4to8;
977
    }
978
    else if (offset_elempack == 8 && out_elempack == 4)
979
    {
980
        pipeline = pipeline_padding_pack8to4;
981
    }
982
    else if (offset_elempack == 8 && out_elempack == 1)
983
    {
984
        pipeline = pipeline_padding_pack8to1;
985
    }
986

987
    cmd.record_pipeline(pipeline, bindings, constants, top_blob);
988

989
    return 0;
990
}
991

992
int Padding_vulkan::forward(const std::vector<VkImageMat>& bottom_blobs, std::vector<VkImageMat>& top_blobs, VkCompute& cmd, const Option& opt) const
993
{
994
    const VkImageMat& bottom_blob = bottom_blobs[0];
995
    const VkImageMat& reference_blob = bottom_blobs[1];
996

997
    VkImageMat& top_blob = top_blobs[0];
998

999
    int _top;
1000
    int _bottom;
1001
    int _left;
1002
    int _right;
1003
    int _front;
1004
    int _behind;
1005
    {
1006
        const int* param_data = reference_blob.mapped();
1007

1008
        _top = param_data[0];
1009
        _bottom = param_data[1];
1010
        _left = param_data[2];
1011
        _right = param_data[3];
1012
        _front = param_data[4];
1013
        _behind = param_data[5];
1014
    }
1015

1016
    int dims = bottom_blob.dims;
1017
    int w = bottom_blob.w;
1018
    int h = bottom_blob.h;
1019
    int d = bottom_blob.d;
1020
    int channels = bottom_blob.c;
1021
    size_t elemsize = bottom_blob.elemsize;
1022
    int elempack = bottom_blob.elempack;
1023

1024
    int outw = 0;
1025
    int outh = 0;
1026
    int outd = 0;
1027
    int outc = 0;
1028

1029
    int offset_elempack;
1030
    int out_elempack;
1031

1032
    if (dims == 1)
1033
    {
1034
        if (_left == 0 && _right == 0)
1035
        {
1036
            top_blob = bottom_blob;
1037
            return 0;
1038
        }
1039

1040
        outw = w * elempack + _left + _right;
1041
        out_elempack = opt.use_shader_pack8 && outw % 8 == 0 ? 8 : outw % 4 == 0 ? 4 : 1;
1042
        offset_elempack = _left == 0 ? elempack : opt.use_shader_pack8 && _left % 8 == 0 ? 8 : _left % 4 == 0 ? 4 : 1;
1043
    }
1044
    else if (dims == 2)
1045
    {
1046
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0)
1047
        {
1048
            top_blob = bottom_blob;
1049
            return 0;
1050
        }
1051

1052
        outw = w + _left + _right;
1053
        outh = h * elempack + _top + _bottom;
1054
        out_elempack = opt.use_shader_pack8 && outh % 8 == 0 ? 8 : outh % 4 == 0 ? 4 : 1;
1055
        offset_elempack = _top == 0 ? elempack : opt.use_shader_pack8 && _top % 8 == 0 ? 8 : _top % 4 == 0 ? 4 : 1;
1056
    }
1057
    else if (dims == 3)
1058
    {
1059
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0 && _front == 0 && _behind == 0)
1060
        {
1061
            top_blob = bottom_blob;
1062
            return 0;
1063
        }
1064

1065
        outw = w + _left + _right;
1066
        outh = h + _top + _bottom;
1067
        outc = channels * elempack + _front + _behind;
1068
        out_elempack = opt.use_shader_pack8 && outc % 8 == 0 ? 8 : outc % 4 == 0 ? 4 : 1;
1069
        offset_elempack = _front == 0 ? elempack : opt.use_shader_pack8 && _front % 8 == 0 ? 8 : _front % 4 == 0 ? 4 : 1;
1070
    }
1071
    else // if (dims == 4)
1072
    {
1073
        if (_top == 0 && _bottom == 0 && _left == 0 && _right == 0 && _front == 0 && _behind == 0)
1074
        {
1075
            top_blob = bottom_blob;
1076
            return 0;
1077
        }
1078

1079
        outw = w + _left + _right;
1080
        outh = h + _top + _bottom;
1081
        outd = d + _front + _behind;
1082
        outc = channels * elempack;
1083
        out_elempack = elempack;
1084
        offset_elempack = elempack;
1085
    }
1086

1087
    offset_elempack = std::min(offset_elempack, elempack);
1088

1089
    size_t out_elemsize = elemsize / elempack * out_elempack;
1090

1091
    if (opt.use_fp16_packed && !opt.use_fp16_storage)
1092
    {
1093
        if (out_elempack == 8) out_elemsize = 8 * 2u;
1094
        if (out_elempack == 4) out_elemsize = 4 * 2u;
1095
        if (out_elempack == 1) out_elemsize = 4u;
1096
    }
1097

1098
    // unpacking
1099
    VkImageMat bottom_blob_unpacked = bottom_blob;
1100
    if (elempack > offset_elempack)
1101
    {
1102
        Option opt_pack1 = opt;
1103
        opt_pack1.blob_vkallocator = opt.workspace_vkallocator;
1104

1105
        vkdev->convert_packing(bottom_blob, bottom_blob_unpacked, offset_elempack, cmd, opt_pack1);
1106
    }
1107

1108
    if (dims == 1)
1109
    {
1110
        top_blob.create(outw / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
1111
    }
1112
    else if (dims == 2)
1113
    {
1114
        top_blob.create(outw, outh / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
1115
    }
1116
    else if (dims == 3)
1117
    {
1118
        top_blob.create(outw, outh, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
1119
    }
1120
    else // if (dims == 4)
1121
    {
1122
        top_blob.create(outw, outh, outd, outc / out_elempack, out_elemsize, out_elempack, opt.blob_vkallocator);
1123
    }
1124
    if (top_blob.empty())
1125
        return -100;
1126

1127
    std::vector<VkImageMat> bindings(3);
1128
    bindings[0] = bottom_blob_unpacked;
1129
    bindings[1] = top_blob;
1130
    bindings[2] = per_channel_pad_data_gpu_image;
1131

1132
    if (dims == 4)
1133
    {
1134
        std::vector<vk_constant_type> constants(15);
1135
        constants[0].i = bottom_blob_unpacked.dims;
1136
        constants[1].i = bottom_blob_unpacked.w;
1137
        constants[2].i = bottom_blob_unpacked.h;
1138
        constants[3].i = bottom_blob_unpacked.d;
1139
        constants[4].i = bottom_blob_unpacked.c;
1140
        constants[5].i = 0;
1141
        constants[6].i = top_blob.dims;
1142
        constants[7].i = top_blob.w;
1143
        constants[8].i = top_blob.h;
1144
        constants[9].i = top_blob.d;
1145
        constants[10].i = top_blob.c;
1146
        constants[11].i = 0;
1147
        constants[12].i = _left;
1148
        constants[13].i = _top;
1149
        constants[14].i = _front;
1150

1151
        const Pipeline* pipeline = out_elempack == 8 ? pipeline_padding_3d_pack8
1152
                                   : out_elempack == 4 ? pipeline_padding_3d_pack4
1153
                                   : pipeline_padding_3d;
1154

1155
        cmd.record_pipeline(pipeline, bindings, constants, top_blob);
1156

1157
        return 0;
1158
    }
1159

1160
    std::vector<vk_constant_type> constants(13);
1161
    constants[0].i = bottom_blob_unpacked.dims;
1162
    constants[1].i = bottom_blob_unpacked.w;
1163
    constants[2].i = bottom_blob_unpacked.h;
1164
    constants[3].i = bottom_blob_unpacked.c;
1165
    constants[4].i = 0;
1166
    constants[5].i = top_blob.dims;
1167
    constants[6].i = top_blob.w;
1168
    constants[7].i = top_blob.h;
1169
    constants[8].i = top_blob.c;
1170
    constants[9].i = 0;
1171
    constants[10].i = _left;
1172
    constants[11].i = _top;
1173
    constants[12].i = _front;
1174

1175
    const Pipeline* pipeline = 0;
1176
    if (offset_elempack == 1 && out_elempack == 1)
1177
    {
1178
        pipeline = pipeline_padding;
1179
    }
1180
    else if (offset_elempack == 4 && out_elempack == 4)
1181
    {
1182
        pipeline = pipeline_padding_pack4;
1183
    }
1184
    else if (offset_elempack == 1 && out_elempack == 4)
1185
    {
1186
        pipeline = pipeline_padding_pack1to4;
1187
    }
1188
    else if (offset_elempack == 4 && out_elempack == 1)
1189
    {
1190
        pipeline = pipeline_padding_pack4to1;
1191
    }
1192
    else if (offset_elempack == 8 && out_elempack == 8)
1193
    {
1194
        pipeline = pipeline_padding_pack8;
1195
    }
1196
    else if (offset_elempack == 1 && out_elempack == 8)
1197
    {
1198
        pipeline = pipeline_padding_pack1to8;
1199
    }
1200
    else if (offset_elempack == 4 && out_elempack == 8)
1201
    {
1202
        pipeline = pipeline_padding_pack4to8;
1203
    }
1204
    else if (offset_elempack == 8 && out_elempack == 4)
1205
    {
1206
        pipeline = pipeline_padding_pack8to4;
1207
    }
1208
    else if (offset_elempack == 8 && out_elempack == 1)
1209
    {
1210
        pipeline = pipeline_padding_pack8to1;
1211
    }
1212

1213
    cmd.record_pipeline(pipeline, bindings, constants, top_blob);
1214

1215
    return 0;
1216
}
1217

1218
} // namespace ncnn
1219

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

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

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

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