From 6561334c5fd12af7810ceee0169a5a01a5ccb4fe Mon Sep 17 00:00:00 2001 From: nihui Date: Thu, 12 Mar 2020 20:47:26 +0800 Subject: [PATCH] conv7x7s2 pack1to4 bf16s neon kernel --- .../arm/convolution_7x7_pack1to4_bf16s.h | 5589 +++++++++++++++++ src/layer/arm/convolution_arm.cpp | 10 + src/layer/arm/packing_arm.cpp | 15 +- 3 files changed, 5611 insertions(+), 3 deletions(-) create mode 100644 src/layer/arm/convolution_7x7_pack1to4_bf16s.h diff --git a/src/layer/arm/convolution_7x7_pack1to4_bf16s.h b/src/layer/arm/convolution_7x7_pack1to4_bf16s.h new file mode 100644 index 000000000..0afb3ff48 --- /dev/null +++ b/src/layer/arm/convolution_7x7_pack1to4_bf16s.h @@ -0,0 +1,5589 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +static void conv7x7s2_pack1to4_bf16s_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Mat& _bias, const Option& opt) +{ + int w = bottom_blob.w; + int inch = bottom_blob.c; + + int outw = top_blob.w; + int outh = top_blob.h; + int outch = top_blob.c; + + Mat top_blob_fp32(outw, outh, opt.num_threads, (size_t)4u * 4, 4, opt.workspace_allocator); + + const int tailstep = w - 2*outw + w; + + const float* bias = _bias; + + #pragma omp parallel for num_threads(opt.num_threads) + for (int p=0; p(0); + const unsigned short* r1 = img0.row(1); + const unsigned short* r2 = img0.row(2); + const unsigned short* r3 = img0.row(3); + const unsigned short* r4 = img0.row(4); + const unsigned short* r5 = img0.row(5); + const unsigned short* r6 = img0.row(6); + + const unsigned short* kptr = kernel.channel(p).row(q); + + int i = 0; + + for (; i < outh; i++) + { + int j = 0; +#if __aarch64__ + for (; j+7(0); + const unsigned short* r1 = img0.row(1); + const unsigned short* r2 = img0.row(2); + const unsigned short* r3 = img0.row(3); + const unsigned short* r4 = img0.row(4); + const unsigned short* r5 = img0.row(5); + const unsigned short* r6 = img0.row(6); + + const unsigned short* kptr = kernel.channel(p).row(q); + + int i = 0; + + for (; i < outh; i++) + { + int j = 0; +#if __aarch64__ + for (; j+7forward_inplace(top_blob, opt); } } + else if (kernel_w == 7 && kernel_h == 7 && dilation_w == 1 && dilation_h == 1 && stride_w == 2 && stride_h == 2) + { + conv7x7s2_pack1to4_bf16s_neon(bottom_blob_bordered, top_blob, weight_data_pack1to4_bf16, bias_data, opt); + + if (activation) + { + activation->forward_inplace(top_blob, opt); + } + } else { // num_output diff --git a/src/layer/arm/packing_arm.cpp b/src/layer/arm/packing_arm.cpp index bfd89c4a2..5ddab845b 100644 --- a/src/layer/arm/packing_arm.cpp +++ b/src/layer/arm/packing_arm.cpp @@ -31,7 +31,13 @@ Packing_arm::Packing_arm() int Packing_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const { - if (opt.use_bf16_storage) + size_t elemsize = bottom_blob.elemsize; + int elempack = bottom_blob.elempack; + + bool elemtype_is_bf16 = (elemsize == 2u && elempack == 1) || (elemsize == 8u && elempack == 4); + bool elemtype_is_fp32 = (elemsize == 4u && elempack == 1) || (elemsize == 16u && elempack == 4); + + if (opt.use_bf16_storage && elemtype_is_bf16) return forward_bf16s(bottom_blob, top_blob, opt); if (use_padding) @@ -39,8 +45,11 @@ int Packing_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Option& op return Packing::forward(bottom_blob, top_blob, opt); } - size_t elemsize = bottom_blob.elemsize; - int elempack = bottom_blob.elempack; + if (!elemtype_is_fp32) + { + // non-fp32 type + return Packing::forward(bottom_blob, top_blob, opt); + } if (elempack == out_elempack) {