ncnn

Форк
0
/
softmax_vulkan.cpp 
568 строк · 21.1 Кб
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 "softmax_vulkan.h"
16

17
#include "layer_shader_type.h"
18

19
namespace ncnn {
20

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

26
    pipeline_softmax_reduce_max = 0;
27
    pipeline_softmax_exp_sub_max = 0;
28
    pipeline_softmax_reduce_sum = 0;
29
    pipeline_softmax_div_sum = 0;
30

31
    pipeline_softmax_reduce_max_pack4 = 0;
32
    pipeline_softmax_exp_sub_max_pack4 = 0;
33
    pipeline_softmax_reduce_sum_pack4 = 0;
34
    pipeline_softmax_div_sum_pack4 = 0;
35

36
    pipeline_softmax_reduce_max_pack8 = 0;
37
    pipeline_softmax_exp_sub_max_pack8 = 0;
38
    pipeline_softmax_reduce_sum_pack8 = 0;
39
    pipeline_softmax_div_sum_pack8 = 0;
40
}
41

42
int Softmax_vulkan::create_pipeline(const Option& opt)
43
{
44
    const Mat& shape = top_shapes.empty() ? Mat() : top_shapes[0];
45
    int positive_axis = axis < 0 ? shape.dims + axis : axis;
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) elempack = opt.use_shader_pack8 && shape.c % 8 == 0 ? 8 : shape.c % 4 == 0 ? 4 : 1;
51

52
    size_t elemsize;
53
    if (opt.use_fp16_storage)
54
    {
55
        elemsize = elempack * 2u;
56
    }
57
    else if (opt.use_fp16_packed)
58
    {
59
        elemsize = elempack == 1 ? 4u : elempack * 2u;
60
    }
61
    else
62
    {
63
        elemsize = elempack * 4u;
64
    }
65

66
    Mat shape_packed;
67
    if (shape.dims == 1) shape_packed = Mat(shape.w / elempack, (void*)0, elemsize, elempack);
68
    if (shape.dims == 2) shape_packed = Mat(shape.w, shape.h / elempack, (void*)0, elemsize, elempack);
69
    if (shape.dims == 3) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack);
70

71
    Mat workspace_shape_packed;
72
    if (shape.dims == 1) // positive_axis == 0
73
    {
74
        workspace_shape_packed = Mat(1, (void*)0, elemsize, elempack);
75
    }
76
    else if (shape.dims == 2 && positive_axis == 0)
77
    {
78
        workspace_shape_packed = Mat(shape.w, (void*)0, elemsize, elempack);
79
    }
80
    else if (shape.dims == 2 && positive_axis == 1)
81
    {
82
        workspace_shape_packed = Mat(shape.h / elempack, (void*)0, elemsize, elempack);
83
    }
84
    else if (shape.dims == 3 && positive_axis == 0)
85
    {
86
        workspace_shape_packed = Mat(shape.w, shape.h, (void*)0, elemsize, elempack);
87
    }
88
    else if (shape.dims == 3 && positive_axis == 1)
89
    {
90
        workspace_shape_packed = Mat(shape.w, shape.c / elempack, (void*)0, elemsize, elempack);
91
    }
92
    else if (shape.dims == 3 && positive_axis == 2)
93
    {
94
        workspace_shape_packed = Mat(shape.h, shape.c / elempack, (void*)0, elemsize, elempack);
95
    }
96

97
    std::vector<vk_specialization_type> specializations(1 + 10);
98
    specializations[0].i = axis;
99
    specializations[1 + 0].i = shape_packed.dims;
100
    specializations[1 + 1].i = shape_packed.w;
101
    specializations[1 + 2].i = shape_packed.h;
102
    specializations[1 + 3].i = shape_packed.c;
103
    specializations[1 + 4].i = shape_packed.cstep;
104
    specializations[1 + 5].i = workspace_shape_packed.dims;
105
    specializations[1 + 6].i = workspace_shape_packed.w;
106
    specializations[1 + 7].i = workspace_shape_packed.h;
107
    specializations[1 + 8].i = workspace_shape_packed.c;
108
    specializations[1 + 9].i = workspace_shape_packed.cstep;
109

110
    {
111
        Mat local_size_xyz;
112
        if (workspace_shape_packed.dims == 1)
113
        {
114
            local_size_xyz.w = std::min(64, workspace_shape_packed.w);
115
            local_size_xyz.h = 1;
116
            local_size_xyz.c = 1;
117
        }
118
        if (workspace_shape_packed.dims == 2)
119
        {
120
            local_size_xyz.w = std::min(8, workspace_shape_packed.w);
121
            local_size_xyz.h = std::min(8, workspace_shape_packed.h);
122
            local_size_xyz.c = 1;
123
        }
124
        if (workspace_shape_packed.dims != 0)
125
        {
126
            local_size_xyz.w = std::min(4, workspace_shape_packed.w);
127
            local_size_xyz.h = std::min(4, workspace_shape_packed.h);
128
            local_size_xyz.c = std::min(4, workspace_shape_packed.c);
129
        }
130

131
        // pack1
132
        {
133
            pipeline_softmax_reduce_max = new Pipeline(vkdev);
134
            pipeline_softmax_reduce_sum = new Pipeline(vkdev);
135

136
            pipeline_softmax_reduce_max->set_optimal_local_size_xyz(local_size_xyz);
137
            pipeline_softmax_reduce_sum->set_optimal_local_size_xyz(local_size_xyz);
138

139
            pipeline_softmax_reduce_max->create(LayerShaderType::softmax_reduce_max, opt, specializations);
140
            pipeline_softmax_reduce_sum->create(LayerShaderType::softmax_reduce_sum, opt, specializations);
141
        }
142

143
        // pack4
144
        {
145
            pipeline_softmax_reduce_max_pack4 = new Pipeline(vkdev);
146
            pipeline_softmax_reduce_sum_pack4 = new Pipeline(vkdev);
147

148
            pipeline_softmax_reduce_max_pack4->set_optimal_local_size_xyz(local_size_xyz);
149
            pipeline_softmax_reduce_sum_pack4->set_optimal_local_size_xyz(local_size_xyz);
150

151
            pipeline_softmax_reduce_max_pack4->create(LayerShaderType::softmax_reduce_max_pack4, opt, specializations);
152
            pipeline_softmax_reduce_sum_pack4->create(LayerShaderType::softmax_reduce_sum_pack4, opt, specializations);
153
        }
154

155
        // pack8
156
        if (opt.use_shader_pack8)
157
        {
158
            pipeline_softmax_reduce_max_pack8 = new Pipeline(vkdev);
159
            pipeline_softmax_reduce_sum_pack8 = new Pipeline(vkdev);
160

161
            pipeline_softmax_reduce_max_pack8->set_optimal_local_size_xyz(local_size_xyz);
162
            pipeline_softmax_reduce_sum_pack8->set_optimal_local_size_xyz(local_size_xyz);
163

164
            pipeline_softmax_reduce_max_pack8->create(LayerShaderType::softmax_reduce_max_pack8, opt, specializations);
165
            pipeline_softmax_reduce_sum_pack8->create(LayerShaderType::softmax_reduce_sum_pack8, opt, specializations);
166
        }
167
    }
168

169
    {
170
        Mat local_size_xyz;
171
        if (shape_packed.dims == 1)
172
        {
173
            local_size_xyz.w = std::min(64, shape_packed.w);
174
            local_size_xyz.h = 1;
175
            local_size_xyz.c = 1;
176
        }
177
        if (shape_packed.dims == 2)
178
        {
179
            local_size_xyz.w = std::min(8, shape_packed.w);
180
            local_size_xyz.h = std::min(8, shape_packed.h);
181
            local_size_xyz.c = 1;
182
        }
183
        if (shape_packed.dims == 3)
184
        {
185
            local_size_xyz.w = std::min(4, shape_packed.w);
186
            local_size_xyz.h = std::min(4, shape_packed.h);
187
            local_size_xyz.c = std::min(4, shape_packed.c);
188
        }
189

190
        // pack1
191
        {
192
            pipeline_softmax_exp_sub_max = new Pipeline(vkdev);
193
            pipeline_softmax_div_sum = new Pipeline(vkdev);
194

195
            pipeline_softmax_exp_sub_max->set_optimal_local_size_xyz(local_size_xyz);
196
            pipeline_softmax_div_sum->set_optimal_local_size_xyz(local_size_xyz);
197

198
            pipeline_softmax_exp_sub_max->create(LayerShaderType::softmax_exp_sub_max, opt, specializations);
199
            pipeline_softmax_div_sum->create(LayerShaderType::softmax_div_sum, opt, specializations);
200
        }
201

202
        // pack4
203
        {
204
            pipeline_softmax_exp_sub_max_pack4 = new Pipeline(vkdev);
205
            pipeline_softmax_div_sum_pack4 = new Pipeline(vkdev);
206

207
            pipeline_softmax_exp_sub_max_pack4->set_optimal_local_size_xyz(local_size_xyz);
208
            pipeline_softmax_div_sum_pack4->set_optimal_local_size_xyz(local_size_xyz);
209

210
            pipeline_softmax_exp_sub_max_pack4->create(LayerShaderType::softmax_exp_sub_max_pack4, opt, specializations);
211
            pipeline_softmax_div_sum_pack4->create(LayerShaderType::softmax_div_sum_pack4, opt, specializations);
212
        }
213

214
        // pack8
215
        if (opt.use_shader_pack8)
216
        {
217
            pipeline_softmax_exp_sub_max_pack8 = new Pipeline(vkdev);
218
            pipeline_softmax_div_sum_pack8 = new Pipeline(vkdev);
219

220
            pipeline_softmax_exp_sub_max_pack8->set_optimal_local_size_xyz(local_size_xyz);
221
            pipeline_softmax_div_sum_pack8->set_optimal_local_size_xyz(local_size_xyz);
222

223
            pipeline_softmax_exp_sub_max_pack8->create(LayerShaderType::softmax_exp_sub_max_pack8, opt, specializations);
224
            pipeline_softmax_div_sum_pack8->create(LayerShaderType::softmax_div_sum_pack8, opt, specializations);
225
        }
226
    }
227

228
    return 0;
229
}
230

231
int Softmax_vulkan::destroy_pipeline(const Option& /*opt*/)
232
{
233
    delete pipeline_softmax_reduce_max;
234
    pipeline_softmax_reduce_max = 0;
235

236
    delete pipeline_softmax_exp_sub_max;
237
    pipeline_softmax_exp_sub_max = 0;
238

239
    delete pipeline_softmax_reduce_sum;
240
    pipeline_softmax_reduce_sum = 0;
241

242
    delete pipeline_softmax_div_sum;
243
    pipeline_softmax_div_sum = 0;
244

245
    delete pipeline_softmax_reduce_max_pack4;
246
    pipeline_softmax_reduce_max_pack4 = 0;
247

248
    delete pipeline_softmax_exp_sub_max_pack4;
249
    pipeline_softmax_exp_sub_max_pack4 = 0;
250

251
    delete pipeline_softmax_reduce_sum_pack4;
252
    pipeline_softmax_reduce_sum_pack4 = 0;
253

254
    delete pipeline_softmax_div_sum_pack4;
255
    pipeline_softmax_div_sum_pack4 = 0;
256

257
    delete pipeline_softmax_reduce_max_pack8;
258
    pipeline_softmax_reduce_max_pack8 = 0;
259

260
    delete pipeline_softmax_exp_sub_max_pack8;
261
    pipeline_softmax_exp_sub_max_pack8 = 0;
262

263
    delete pipeline_softmax_reduce_sum_pack8;
264
    pipeline_softmax_reduce_sum_pack8 = 0;
265

266
    delete pipeline_softmax_div_sum_pack8;
267
    pipeline_softmax_div_sum_pack8 = 0;
268

269
    return 0;
270
}
271

272
int Softmax_vulkan::forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const
273
{
274
    int dims = bottom_top_blob.dims;
275
    int w = bottom_top_blob.w;
276
    int h = bottom_top_blob.h;
277
    int channels = bottom_top_blob.c;
278
    size_t elemsize = bottom_top_blob.elemsize;
279
    int elempack = bottom_top_blob.elempack;
280
    int positive_axis = axis < 0 ? dims + axis : axis;
281

282
    VkMat max_workspace;
283
    VkMat sum_workspace;
284

285
    if (dims == 1) // positive_axis == 0
286
    {
287
        max_workspace.create(1, elemsize, elempack, opt.workspace_vkallocator);
288
        sum_workspace.create(1, elemsize, elempack, opt.workspace_vkallocator);
289
    }
290
    else if (dims == 2 && positive_axis == 0)
291
    {
292
        max_workspace.create(w, elemsize, elempack, opt.workspace_vkallocator);
293
        sum_workspace.create(w, elemsize, elempack, opt.workspace_vkallocator);
294
    }
295
    else if (dims == 2 && positive_axis == 1)
296
    {
297
        max_workspace.create(h, elemsize, elempack, opt.workspace_vkallocator);
298
        sum_workspace.create(h, elemsize, elempack, opt.workspace_vkallocator);
299
    }
300
    else if (dims == 3 && positive_axis == 0)
301
    {
302
        max_workspace.create(w, h, elemsize, elempack, opt.workspace_vkallocator);
303
        sum_workspace.create(w, h, elemsize, elempack, opt.workspace_vkallocator);
304
    }
305
    else if (dims == 3 && positive_axis == 1)
306
    {
307
        max_workspace.create(w, channels, elemsize, elempack, opt.workspace_vkallocator);
308
        sum_workspace.create(w, channels, elemsize, elempack, opt.workspace_vkallocator);
309
    }
310
    else if (dims == 3 && positive_axis == 2)
311
    {
312
        max_workspace.create(h, channels, elemsize, elempack, opt.workspace_vkallocator);
313
        sum_workspace.create(h, channels, elemsize, elempack, opt.workspace_vkallocator);
314
    }
315

316
    // reduce max
317
    {
318
        std::vector<VkMat> bindings(2);
319
        bindings[0] = bottom_top_blob;
320
        bindings[1] = max_workspace;
321

322
        std::vector<vk_constant_type> constants(10);
323
        constants[0].i = bottom_top_blob.dims;
324
        constants[1].i = bottom_top_blob.w;
325
        constants[2].i = bottom_top_blob.h;
326
        constants[3].i = bottom_top_blob.c;
327
        constants[4].i = bottom_top_blob.cstep;
328
        constants[5].i = max_workspace.dims;
329
        constants[6].i = max_workspace.w;
330
        constants[7].i = max_workspace.h;
331
        constants[8].i = max_workspace.c;
332
        constants[9].i = max_workspace.cstep;
333

334
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_reduce_max_pack8
335
                                   : elempack == 4 ? pipeline_softmax_reduce_max_pack4
336
                                   : pipeline_softmax_reduce_max;
337

338
        cmd.record_pipeline(pipeline, bindings, constants, max_workspace);
339
    }
340

341
    // exp( v - max )
342
    {
343
        std::vector<VkMat> bindings(2);
344
        bindings[0] = bottom_top_blob;
345
        bindings[1] = max_workspace;
346

347
        std::vector<vk_constant_type> constants(10);
348
        constants[0].i = bottom_top_blob.dims;
349
        constants[1].i = bottom_top_blob.w;
350
        constants[2].i = bottom_top_blob.h;
351
        constants[3].i = bottom_top_blob.c;
352
        constants[4].i = bottom_top_blob.cstep;
353
        constants[5].i = max_workspace.dims;
354
        constants[6].i = max_workspace.w;
355
        constants[7].i = max_workspace.h;
356
        constants[8].i = max_workspace.c;
357
        constants[9].i = max_workspace.cstep;
358

359
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_exp_sub_max_pack8
360
                                   : elempack == 4 ? pipeline_softmax_exp_sub_max_pack4
361
                                   : pipeline_softmax_exp_sub_max;
362

363
        cmd.record_pipeline(pipeline, bindings, constants, bottom_top_blob);
364
    }
365

366
    // reduce sum
367
    {
368
        std::vector<VkMat> bindings(2);
369
        bindings[0] = bottom_top_blob;
370
        bindings[1] = sum_workspace;
371

372
        std::vector<vk_constant_type> constants(10);
373
        constants[0].i = bottom_top_blob.dims;
374
        constants[1].i = bottom_top_blob.w;
375
        constants[2].i = bottom_top_blob.h;
376
        constants[3].i = bottom_top_blob.c;
377
        constants[4].i = bottom_top_blob.cstep;
378
        constants[5].i = sum_workspace.dims;
379
        constants[6].i = sum_workspace.w;
380
        constants[7].i = sum_workspace.h;
381
        constants[8].i = sum_workspace.c;
382
        constants[9].i = sum_workspace.cstep;
383

384
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_reduce_sum_pack8
385
                                   : elempack == 4 ? pipeline_softmax_reduce_sum_pack4
386
                                   : pipeline_softmax_reduce_sum;
387

388
        cmd.record_pipeline(pipeline, bindings, constants, sum_workspace);
389
    }
390

391
    // div sum
392
    {
393
        std::vector<VkMat> bindings(2);
394
        bindings[0] = bottom_top_blob;
395
        bindings[1] = sum_workspace;
396

397
        std::vector<vk_constant_type> constants(10);
398
        constants[0].i = bottom_top_blob.dims;
399
        constants[1].i = bottom_top_blob.w;
400
        constants[2].i = bottom_top_blob.h;
401
        constants[3].i = bottom_top_blob.c;
402
        constants[4].i = bottom_top_blob.cstep;
403
        constants[5].i = sum_workspace.dims;
404
        constants[6].i = sum_workspace.w;
405
        constants[7].i = sum_workspace.h;
406
        constants[8].i = sum_workspace.c;
407
        constants[9].i = sum_workspace.cstep;
408

409
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_div_sum_pack8
410
                                   : elempack == 4 ? pipeline_softmax_div_sum_pack4
411
                                   : pipeline_softmax_div_sum;
412

413
        cmd.record_pipeline(pipeline, bindings, constants, bottom_top_blob);
414
    }
415

416
    return 0;
417
}
418

419
int Softmax_vulkan::forward_inplace(VkImageMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const
420
{
421
    int dims = bottom_top_blob.dims;
422
    int w = bottom_top_blob.w;
423
    int h = bottom_top_blob.h;
424
    int channels = bottom_top_blob.c;
425
    size_t elemsize = bottom_top_blob.elemsize;
426
    int elempack = bottom_top_blob.elempack;
427
    int positive_axis = axis < 0 ? dims + axis : axis;
428

429
    VkImageMat max_workspace;
430
    VkImageMat sum_workspace;
431

432
    if (dims == 1) // positive_axis == 0
433
    {
434
        max_workspace.create(1, elemsize, elempack, opt.workspace_vkallocator);
435
        sum_workspace.create(1, elemsize, elempack, opt.workspace_vkallocator);
436
    }
437
    else if (dims == 2 && positive_axis == 0)
438
    {
439
        max_workspace.create(w, elemsize, elempack, opt.workspace_vkallocator);
440
        sum_workspace.create(w, elemsize, elempack, opt.workspace_vkallocator);
441
    }
442
    else if (dims == 2 && positive_axis == 1)
443
    {
444
        max_workspace.create(h, elemsize, elempack, opt.workspace_vkallocator);
445
        sum_workspace.create(h, elemsize, elempack, opt.workspace_vkallocator);
446
    }
447
    else if (dims == 3 && positive_axis == 0)
448
    {
449
        max_workspace.create(w, h, elemsize, elempack, opt.workspace_vkallocator);
450
        sum_workspace.create(w, h, elemsize, elempack, opt.workspace_vkallocator);
451
    }
452
    else if (dims == 3 && positive_axis == 1)
453
    {
454
        max_workspace.create(w, channels, elemsize, elempack, opt.workspace_vkallocator);
455
        sum_workspace.create(w, channels, elemsize, elempack, opt.workspace_vkallocator);
456
    }
457
    else if (dims == 3 && positive_axis == 2)
458
    {
459
        max_workspace.create(h, channels, elemsize, elempack, opt.workspace_vkallocator);
460
        sum_workspace.create(h, channels, elemsize, elempack, opt.workspace_vkallocator);
461
    }
462

463
    // reduce max
464
    {
465
        std::vector<VkImageMat> bindings(2);
466
        bindings[0] = bottom_top_blob;
467
        bindings[1] = max_workspace;
468

469
        std::vector<vk_constant_type> constants(10);
470
        constants[0].i = bottom_top_blob.dims;
471
        constants[1].i = bottom_top_blob.w;
472
        constants[2].i = bottom_top_blob.h;
473
        constants[3].i = bottom_top_blob.c;
474
        constants[4].i = 0; //bottom_top_blob.cstep;
475
        constants[5].i = max_workspace.dims;
476
        constants[6].i = max_workspace.w;
477
        constants[7].i = max_workspace.h;
478
        constants[8].i = max_workspace.c;
479
        constants[9].i = 0; //max_workspace.cstep;
480

481
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_reduce_max_pack8
482
                                   : elempack == 4 ? pipeline_softmax_reduce_max_pack4
483
                                   : pipeline_softmax_reduce_max;
484

485
        cmd.record_pipeline(pipeline, bindings, constants, max_workspace);
486
    }
487

488
    // exp( v - max )
489
    {
490
        std::vector<VkImageMat> bindings(3);
491
        bindings[0] = bottom_top_blob;
492
        bindings[1] = bottom_top_blob;
493
        bindings[2] = max_workspace;
494

495
        std::vector<vk_constant_type> constants(10);
496
        constants[0].i = bottom_top_blob.dims;
497
        constants[1].i = bottom_top_blob.w;
498
        constants[2].i = bottom_top_blob.h;
499
        constants[3].i = bottom_top_blob.c;
500
        constants[4].i = 0; //bottom_top_blob.cstep;
501
        constants[5].i = max_workspace.dims;
502
        constants[6].i = max_workspace.w;
503
        constants[7].i = max_workspace.h;
504
        constants[8].i = max_workspace.c;
505
        constants[9].i = 0; //max_workspace.cstep;
506

507
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_exp_sub_max_pack8
508
                                   : elempack == 4 ? pipeline_softmax_exp_sub_max_pack4
509
                                   : pipeline_softmax_exp_sub_max;
510

511
        cmd.record_pipeline(pipeline, bindings, constants, bottom_top_blob);
512
    }
513

514
    // reduce sum
515
    {
516
        std::vector<VkImageMat> bindings(2);
517
        bindings[0] = bottom_top_blob;
518
        bindings[1] = sum_workspace;
519

520
        std::vector<vk_constant_type> constants(10);
521
        constants[0].i = bottom_top_blob.dims;
522
        constants[1].i = bottom_top_blob.w;
523
        constants[2].i = bottom_top_blob.h;
524
        constants[3].i = bottom_top_blob.c;
525
        constants[4].i = 0; //bottom_top_blob.cstep;
526
        constants[5].i = sum_workspace.dims;
527
        constants[6].i = sum_workspace.w;
528
        constants[7].i = sum_workspace.h;
529
        constants[8].i = sum_workspace.c;
530
        constants[9].i = 0; //sum_workspace.cstep;
531

532
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_reduce_sum_pack8
533
                                   : elempack == 4 ? pipeline_softmax_reduce_sum_pack4
534
                                   : pipeline_softmax_reduce_sum;
535

536
        cmd.record_pipeline(pipeline, bindings, constants, sum_workspace);
537
    }
538

539
    // div sum
540
    {
541
        std::vector<VkImageMat> bindings(3);
542
        bindings[0] = bottom_top_blob;
543
        bindings[1] = bottom_top_blob;
544
        bindings[2] = sum_workspace;
545

546
        std::vector<vk_constant_type> constants(10);
547
        constants[0].i = bottom_top_blob.dims;
548
        constants[1].i = bottom_top_blob.w;
549
        constants[2].i = bottom_top_blob.h;
550
        constants[3].i = bottom_top_blob.c;
551
        constants[4].i = 0; //bottom_top_blob.cstep;
552
        constants[5].i = sum_workspace.dims;
553
        constants[6].i = sum_workspace.w;
554
        constants[7].i = sum_workspace.h;
555
        constants[8].i = sum_workspace.c;
556
        constants[9].i = 0; //sum_workspace.cstep;
557

558
        const Pipeline* pipeline = elempack == 8 ? pipeline_softmax_div_sum_pack8
559
                                   : elempack == 4 ? pipeline_softmax_div_sum_pack4
560
                                   : pipeline_softmax_div_sum;
561

562
        cmd.record_pipeline(pipeline, bindings, constants, bottom_top_blob);
563
    }
564

565
    return 0;
566
}
567

568
} // namespace ncnn
569

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

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

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

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