| @@ -38,29 +38,25 @@ int AbsVal_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vabsq_f32(_p); | |||
| vst1q_f32(ptr, _p); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vabsq_f32(_p); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| ptr += 4; | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __ARM_NEON | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| @@ -35,82 +35,78 @@ int BatchNorm_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) cons | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| if (dims == 1) | |||
| { | |||
| if (dims == 1) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int w = bottom_top_blob.w; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + i * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + i * 4); | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + i * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + i * 4); | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + i * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + i * 4); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + i * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + i * 4); | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float* ptr = bottom_top_blob.row(i); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int c = bottom_top_blob.c; | |||
| int size = w * h; | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int c = bottom_top_blob.c; | |||
| int size = w * h; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < c; q++) | |||
| { | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + q * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + q * 4); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < c; q++) | |||
| { | |||
| float32x4_t _a = vld1q_f32((const float*)a_data + q * 4); | |||
| float32x4_t _b = vld1q_f32((const float*)b_data + q * 4); | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_a, _p, _b); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| ptr += 4; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __ARM_NEON | |||
| if (dims != 3) | |||
| @@ -38,16 +38,14 @@ int Concat_arm::create_pipeline(const Option& opt) | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| { | |||
| { | |||
| packing_pack4 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| packing_pack4 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 4); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 4); | |||
| packing_pack4->load_param(pd); | |||
| packing_pack4->load_param(pd); | |||
| packing_pack4->create_pipeline(opt); | |||
| } | |||
| packing_pack4->create_pipeline(opt); | |||
| } | |||
| #endif // __ARM_NEON | |||
| @@ -129,7 +129,7 @@ int Convolution_arm::create_pipeline(const Option& opt) | |||
| return create_pipeline_int8_arm(opt); | |||
| } | |||
| if (opt.use_packing_layout == false && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| if ((!support_packing || !opt.use_packing_layout) && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| { | |||
| convolution_dilation1 = ncnn::create_layer(ncnn::LayerType::Convolution); | |||
| @@ -174,8 +174,8 @@ int Convolution_arm::create_pipeline(const Option& opt) | |||
| const int maxk = kernel_w * kernel_h; | |||
| const int num_input = weight_data_size / maxk / num_output; | |||
| int elempack = (opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| #if __ARM_NEON | |||
| // pack4 | |||
| @@ -488,14 +488,14 @@ int Convolution_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Option | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| top_blob.create(outw, outh, num_output / out_elempack, out_elemsize, out_elempack, opt.blob_allocator); | |||
| if (top_blob.empty()) | |||
| return -100; | |||
| if (opt.use_packing_layout == false && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| if ((!support_packing || !opt.use_packing_layout) && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| { | |||
| if (outw >= dilation_w && outh >= dilation_h) | |||
| { | |||
| @@ -1021,8 +1021,8 @@ int Convolution_arm::create_pipeline_bf16s(const Option& opt) | |||
| const int maxk = kernel_w * kernel_h; | |||
| const int num_input = weight_data_size / maxk / num_output; | |||
| int elempack = (opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| #if __ARM_NEON | |||
| // pack4 | |||
| @@ -1243,7 +1243,7 @@ int Convolution_arm::forward_bf16s(const Mat& bottom_blob, Mat& top_blob, const | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| top_blob.create(outw, outh, num_output / out_elempack, out_elemsize, out_elempack, opt.blob_allocator); | |||
| @@ -1251,7 +1251,7 @@ int Convolution_arm::forward_bf16s(const Mat& bottom_blob, Mat& top_blob, const | |||
| return -100; | |||
| // FIXME | |||
| // if (opt.use_packing_layout == false && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| // if ((!support_packing || !opt.use_packing_layout) && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| // { | |||
| // return forwardDilation_arm(bottom_blob_bordered, top_blob, opt); | |||
| // } | |||
| @@ -120,7 +120,7 @@ int ConvolutionDepthWise_arm::create_pipeline(const Option& opt) | |||
| } | |||
| else | |||
| { | |||
| int elempack = (opt.use_packing_layout && channels % 4 == 0) ? 4 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && channels % 4 == 0) ? 4 : 1; | |||
| #if __ARM_NEON | |||
| // pack4 | |||
| @@ -288,7 +288,7 @@ int ConvolutionDepthWise_arm::forward(const Mat& bottom_blob, Mat& top_blob, con | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| top_blob.create(outw, outh, num_output / out_elempack, out_elemsize, out_elempack, opt.blob_allocator); | |||
| @@ -462,8 +462,8 @@ int ConvolutionDepthWise_arm::forward(const Mat& bottom_blob, Mat& top_blob, con | |||
| const int channels_g = channels * elempack / group; | |||
| const int num_output_g = num_output / group; | |||
| int g_elempack = (opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| int g_elempack = (support_packing && opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (support_packing && opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| // unpacking | |||
| Mat bottom_blob_bordered_unpacked = bottom_blob_bordered; | |||
| @@ -530,7 +530,7 @@ int ConvolutionDepthWise_arm::forward_bf16s(const Mat& bottom_blob, Mat& top_blo | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| top_blob.create(outw, outh, num_output / out_elempack, out_elemsize, out_elempack, opt.blob_allocator); | |||
| @@ -780,8 +780,8 @@ int ConvolutionDepthWise_arm::forward_bf16s(const Mat& bottom_blob, Mat& top_blo | |||
| const int channels_g = channels * elempack / group; | |||
| const int num_output_g = num_output / group; | |||
| int g_elempack = (opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| int g_elempack = (support_packing && opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (support_packing && opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| // unpacking | |||
| Mat bottom_blob_bordered_unpacked = bottom_blob_bordered; | |||
| @@ -98,8 +98,8 @@ int Deconvolution_arm::create_pipeline(const Option& opt) | |||
| } | |||
| } | |||
| int elempack = (opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && num_input % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| #if __ARM_NEON | |||
| // pack4 | |||
| @@ -294,7 +294,7 @@ int Deconvolution_arm::forward(const Mat& bottom_blob, Mat& top_blob, const Opti | |||
| int outw = (w - 1) * stride_w + kernel_extent_w; | |||
| int outh = (h - 1) * stride_h + kernel_extent_h; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| Mat top_blob_bordered; | |||
| @@ -43,7 +43,7 @@ int DeconvolutionDepthWise_arm::create_pipeline(const Option& opt) | |||
| // depth-wise | |||
| if (channels == group && group == num_output) | |||
| { | |||
| int elempack = (opt.use_packing_layout && channels % 4 == 0) ? 4 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && channels % 4 == 0) ? 4 : 1; | |||
| Mat weight_data_transposed(weight_data.w); | |||
| { | |||
| @@ -171,7 +171,7 @@ int DeconvolutionDepthWise_arm::forward(const Mat& bottom_blob, Mat& top_blob, c | |||
| int outw = (w - 1) * stride_w + kernel_extent_w; | |||
| int outh = (h - 1) * stride_h + kernel_extent_h; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 4 == 0) ? 4 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| Mat top_blob_bordered; | |||
| @@ -345,8 +345,8 @@ int DeconvolutionDepthWise_arm::forward(const Mat& bottom_blob, Mat& top_blob, c | |||
| const int channels_g = channels * elempack / group; | |||
| const int num_output_g = num_output / group; | |||
| int g_elempack = (opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| int g_elempack = (support_packing && opt.use_packing_layout && channels_g % 4 == 0) ? 4 : 1; | |||
| int out_g_elempack = (support_packing && opt.use_packing_layout && num_output_g % 4 == 0) ? 4 : 1; | |||
| // unpacking | |||
| Mat bottom_blob_unpacked = bottom_blob; | |||
| @@ -40,67 +40,63 @@ int Dropout_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| float32x4_t _scale = vdupq_n_f32(scale); | |||
| float32x4_t _scale = vdupq_n_f32(scale); | |||
| if (dims == 1) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _scale); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| } | |||
| if (dims == 1) | |||
| if (dims == 2) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| float* ptr = bottom_top_blob.row(i); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _scale); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| if (dims == 3) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _scale); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| if (dims == 3) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _scale); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _scale); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __ARM_NEON | |||
| return Dropout::forward_inplace(bottom_top_blob, opt); | |||
| @@ -35,105 +35,101 @@ int PReLU_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| float32x4_t _zero = vdupq_n_f32(0.f); | |||
| if (dims == 1) | |||
| { | |||
| float32x4_t _zero = vdupq_n_f32(0.f); | |||
| int w = bottom_top_blob.w; | |||
| if (dims == 1) | |||
| if (num_slope > 1) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| const float* slope = slope_data; | |||
| if (num_slope > 1) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| const float* slope = slope_data; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _slope = vld1q_f32(slope + i * 4); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _slope = vld1q_f32(slope + i * 4); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| else | |||
| } | |||
| else | |||
| { | |||
| float32x4_t _slope = vdupq_n_f32(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float32x4_t _slope = vdupq_n_f32(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| if (dims == 2) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _slope = num_slope > 1 ? vld1q_f32((const float*)slope_data + i * 4) : vdupq_n_f32(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _slope = num_slope > 1 ? vld1q_f32((const float*)slope_data + i * 4) : vdupq_n_f32(slope_data[0]); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| if (dims == 3) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _slope = num_slope > 1 ? vld1q_f32((const float*)slope_data + q * 4) : vdupq_n_f32(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _slope = num_slope > 1 ? vld1q_f32((const float*)slope_data + q * 4) : vdupq_n_f32(slope_data[0]); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| uint32x4_t _lemask = vcleq_f32(_p, _zero); | |||
| float32x4_t _ps = vmulq_f32(_p, _slope); | |||
| _p = vbslq_f32(_lemask, _ps, _p); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __ARM_NEON | |||
| if (dims != 3) | |||
| @@ -38,139 +38,135 @@ int Scale_arm::forward_inplace(std::vector<Mat>& bottom_top_blobs, const Option& | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| if (dims == 1) | |||
| { | |||
| if (dims == 1) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int w = bottom_top_blob.w; | |||
| const float* scale = scale_blob; | |||
| if (bias_term) | |||
| const float* scale = scale_blob; | |||
| if (bias_term) | |||
| { | |||
| const float* bias = bias_data; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| const float* bias = bias_data; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _s = vld1q_f32(scale + i * 4); | |||
| float32x4_t _bias = vld1q_f32(bias + i * 4); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _s = vld1q_f32(scale + i * 4); | |||
| float32x4_t _bias = vld1q_f32(bias + i * 4); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| else | |||
| } | |||
| else | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float* ptr = (float*)bottom_top_blob + i * 4; | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _s = vld1q_f32(scale + i * 4); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| float32x4_t _s = vld1q_f32(scale + i * 4); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| } | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| if (bias_term) | |||
| if (bias_term) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + i * 4); | |||
| float32x4_t _bias = vld1q_f32((const float*)bias_data + i * 4); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + i * 4); | |||
| float32x4_t _bias = vld1q_f32((const float*)bias_data + i * 4); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| else | |||
| } | |||
| else | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + i * 4); | |||
| float* ptr = bottom_top_blob.row(i); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + i * 4); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| if (bias_term) | |||
| if (bias_term) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + q * 4); | |||
| float32x4_t _bias = vld1q_f32((const float*)bias_data + q * 4); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + q * 4); | |||
| float32x4_t _bias = vld1q_f32((const float*)bias_data + q * 4); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmlaq_f32(_bias, _p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| } | |||
| else | |||
| } | |||
| else | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + q * 4); | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| float32x4_t _s = vld1q_f32((const float*)scale_blob + q * 4); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float32x4_t _p = vld1q_f32(ptr); | |||
| _p = vmulq_f32(_p, _s); | |||
| vst1q_f32(ptr, _p); | |||
| ptr += 4; | |||
| } | |||
| ptr += 4; | |||
| } | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __ARM_NEON | |||
| if (dims != 3) | |||
| @@ -40,16 +40,14 @@ int Slice_arm::create_pipeline(const Option& opt) | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| { | |||
| { | |||
| packing_pack1 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| packing_pack1 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 1); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 1); | |||
| packing_pack1->load_param(pd); | |||
| packing_pack1->load_param(pd); | |||
| packing_pack1->create_pipeline(opt); | |||
| } | |||
| packing_pack1->create_pipeline(opt); | |||
| } | |||
| #endif // __ARM_NEON | |||
| @@ -273,63 +273,59 @@ int UnaryOp_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __ARM_NEON | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 4) | |||
| { | |||
| if (elempack == 4) | |||
| { | |||
| if (op_type == Operation_ABS) | |||
| return unary_op_inplace<unary_op_abs<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_NEG) | |||
| return unary_op_inplace<unary_op_neg<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ABS) | |||
| return unary_op_inplace<unary_op_abs<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_FLOOR) | |||
| return unary_op_inplace<unary_op_floor<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_NEG) | |||
| return unary_op_inplace<unary_op_neg<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_CEIL) | |||
| return unary_op_inplace<unary_op_ceil<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_FLOOR) | |||
| return unary_op_inplace<unary_op_floor<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SQUARE) | |||
| return unary_op_inplace<unary_op_square<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_CEIL) | |||
| return unary_op_inplace<unary_op_ceil<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SQRT) | |||
| return unary_op_inplace<unary_op_sqrt<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SQUARE) | |||
| return unary_op_inplace<unary_op_square<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_RSQRT) | |||
| return unary_op_inplace<unary_op_rsqrt<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SQRT) | |||
| return unary_op_inplace<unary_op_sqrt<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_EXP) | |||
| return unary_op_inplace<unary_op_exp<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_RSQRT) | |||
| return unary_op_inplace<unary_op_rsqrt<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_LOG) | |||
| return unary_op_inplace<unary_op_log<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_EXP) | |||
| return unary_op_inplace<unary_op_exp<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SIN) | |||
| return unary_op_inplace<unary_op_sin<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_LOG) | |||
| return unary_op_inplace<unary_op_log<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_COS) | |||
| return unary_op_inplace<unary_op_cos<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_SIN) | |||
| return unary_op_inplace<unary_op_sin<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_TAN) | |||
| return unary_op_inplace<unary_op_tan<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_COS) | |||
| return unary_op_inplace<unary_op_cos<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ASIN) | |||
| return unary_op_inplace<unary_op_asin<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_TAN) | |||
| return unary_op_inplace<unary_op_tan<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ACOS) | |||
| return unary_op_inplace<unary_op_acos<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ASIN) | |||
| return unary_op_inplace<unary_op_asin<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ATAN) | |||
| return unary_op_inplace<unary_op_atan<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ACOS) | |||
| return unary_op_inplace<unary_op_acos<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_RECIPROCAL) | |||
| return unary_op_inplace<unary_op_reciprocal<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_ATAN) | |||
| return unary_op_inplace<unary_op_atan<float32x4_t> >(bottom_top_blob, opt); | |||
| if (op_type == Operation_TANH) | |||
| return unary_op_inplace<unary_op_tanh<float32x4_t> >(bottom_top_blob, opt); | |||
| } | |||
| if (op_type == Operation_RECIPROCAL) | |||
| return unary_op_inplace<unary_op_reciprocal<float32x4_t> >(bottom_top_blob, opt); | |||
| } // opt.use_packing_layout | |||
| if (op_type == Operation_TANH) | |||
| return unary_op_inplace<unary_op_tanh<float32x4_t> >(bottom_top_blob, opt); | |||
| } | |||
| #endif // __ARM_NEON | |||
| return UnaryOp::forward_inplace(bottom_top_blob, opt); | |||
| @@ -36,16 +36,14 @@ int Concat_x86::create_pipeline(const Option& opt) | |||
| #if __AVX__ | |||
| if (opt.use_packing_layout) | |||
| { | |||
| { | |||
| packing_pack8 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| packing_pack8 = ncnn::create_layer(ncnn::LayerType::Packing); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 8); | |||
| ncnn::ParamDict pd; | |||
| pd.set(0, 8); | |||
| packing_pack8->load_param(pd); | |||
| packing_pack8->load_param(pd); | |||
| packing_pack8->create_pipeline(opt); | |||
| } | |||
| packing_pack8->create_pipeline(opt); | |||
| } | |||
| #endif // __AVX__ | |||
| @@ -180,8 +180,8 @@ int Convolution_x86::create_pipeline(const Option& opt) | |||
| } | |||
| const int maxk = kernel_w * kernel_h; | |||
| int elempack = (opt.use_packing_layout && num_input % 8 == 0) ? 8 : 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && num_input % 8 == 0) ? 8 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| // pack8 | |||
| if (elempack == 8 && out_elempack == 8) | |||
| { | |||
| @@ -499,12 +499,12 @@ int Convolution_x86::forward(const Mat& bottom_blob, Mat& top_blob, const Option | |||
| return forward_int8_x86(bottom_blob, top_blob, opt); | |||
| } | |||
| if (opt.use_packing_layout == false && (dilation_w > 1 || dilation_h > 1) && (stride_w > 1 || stride_h > 1)) | |||
| if ((!support_packing || !opt.use_packing_layout) && (dilation_w > 1 || dilation_h > 1) && (stride_w > 1 || stride_h > 1)) | |||
| { | |||
| return Convolution::forward(bottom_blob, top_blob, opt); | |||
| } | |||
| if (opt.use_packing_layout == false && (dilation_w > 1 || dilation_h > 1) && dilation_w != dilation_h) | |||
| if ((!support_packing || !opt.use_packing_layout) && (dilation_w > 1 || dilation_h > 1) && dilation_w != dilation_h) | |||
| { | |||
| return Convolution::forward(bottom_blob, top_blob, opt); | |||
| } | |||
| @@ -528,7 +528,7 @@ int Convolution_x86::forward(const Mat& bottom_blob, Mat& top_blob, const Option | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| // fprintf(stderr, "elempack = %d out_elempack = %d ACTIVATION TYPE = %d \n",elempack,out_elempack,activation_type ); | |||
| @@ -536,7 +536,7 @@ int Convolution_x86::forward(const Mat& bottom_blob, Mat& top_blob, const Option | |||
| if (top_blob.empty()) | |||
| return -100; | |||
| if (opt.use_packing_layout == false && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| if ((!support_packing || !opt.use_packing_layout) && kernel_w == kernel_h && dilation_w != 1 && dilation_h == dilation_w && stride_w == 1 && stride_h == 1) | |||
| { | |||
| if (outw >= dilation_w && outh >= dilation_h) | |||
| { | |||
| @@ -107,7 +107,7 @@ int ConvolutionDepthWise_x86::create_pipeline(const Option& opt) | |||
| group_ops.clear(); | |||
| if (channels == group && group == num_output) | |||
| { | |||
| int elempack = (opt.use_packing_layout && channels % 8 == 0) ? 8 : 1; | |||
| int elempack = (support_packing && opt.use_packing_layout && channels % 8 == 0) ? 8 : 1; | |||
| #if __AVX__ | |||
| // pack8 | |||
| if (elempack == 8) | |||
| @@ -249,7 +249,7 @@ int ConvolutionDepthWise_x86::forward(const Mat& bottom_blob, Mat& top_blob, con | |||
| int outw = (w - kernel_extent_w) / stride_w + 1; | |||
| int outh = (h - kernel_extent_h) / stride_h + 1; | |||
| int out_elempack = (opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| int out_elempack = (support_packing && opt.use_packing_layout && num_output % 8 == 0) ? 8 : 1; | |||
| size_t out_elemsize = elemsize / elempack * out_elempack; | |||
| top_blob.create(outw, outh, num_output / out_elempack, out_elemsize, out_elempack, opt.blob_allocator); | |||
| @@ -402,8 +402,8 @@ int ConvolutionDepthWise_x86::forward(const Mat& bottom_blob, Mat& top_blob, con | |||
| const int channels_g = channels * elempack / group; | |||
| const int num_output_g = num_output / group; | |||
| int g_elempack = (opt.use_packing_layout && channels_g % 8 == 0) ? 8 : 1; | |||
| int out_g_elempack = (opt.use_packing_layout && num_output_g % 8 == 0) ? 8 : 1; | |||
| int g_elempack = (support_packing && opt.use_packing_layout && channels_g % 8 == 0) ? 8 : 1; | |||
| int out_g_elempack = (support_packing && opt.use_packing_layout && num_output_g % 8 == 0) ? 8 : 1; | |||
| // unpacking | |||
| Mat bottom_blob_bordered_unpacked = bottom_blob_bordered; | |||
| @@ -40,67 +40,63 @@ int Dropout_x86::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __AVX__ | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 8) | |||
| { | |||
| if (elempack == 8) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| __m256 _scale = _mm256_set1_ps(scale); | |||
| __m256 _scale = _mm256_set1_ps(scale); | |||
| if (dims == 1) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _p = _mm256_mul_ps(_p, _scale); | |||
| _mm256_storeu_ps(ptr, _p); | |||
| } | |||
| } | |||
| if (dims == 1) | |||
| if (dims == 2) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| float* ptr = bottom_top_blob.row(i); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _p = _mm256_mul_ps(_p, _scale); | |||
| _mm256_storeu_ps(ptr, _p); | |||
| ptr += 8; | |||
| } | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| if (dims == 3) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _p = _mm256_mul_ps(_p, _scale); | |||
| _mm256_storeu_ps(ptr, _p); | |||
| ptr += 8; | |||
| } | |||
| } | |||
| } | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| if (dims == 3) | |||
| { | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _p = _mm256_mul_ps(_p, _scale); | |||
| _mm256_storeu_ps(ptr, _p); | |||
| ptr += 8; | |||
| } | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _p = _mm256_mul_ps(_p, _scale); | |||
| _mm256_storeu_ps(ptr, _p); | |||
| ptr += 8; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __AVX__ | |||
| return Dropout::forward_inplace(bottom_top_blob, opt); | |||
| @@ -35,87 +35,83 @@ int PReLU_x86::forward_inplace(Mat& bottom_top_blob, const Option& opt) const | |||
| int elempack = bottom_top_blob.elempack; | |||
| #if __AVX__ | |||
| if (opt.use_packing_layout) | |||
| if (elempack == 8) | |||
| { | |||
| if (elempack == 8) | |||
| if (dims == 1) | |||
| { | |||
| if (dims == 1) | |||
| int w = bottom_top_blob.w; | |||
| if (num_slope > 1) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| const float* slope = slope_data; | |||
| if (num_slope > 1) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| const float* slope = slope_data; | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| __m256 _slope = _mm256_loadu_ps(slope + i * 8); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| } | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| __m256 _slope = _mm256_loadu_ps(slope + i * 8); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| } | |||
| else | |||
| } | |||
| else | |||
| { | |||
| __m256 _slope = _mm256_set1_ps(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| __m256 _slope = _mm256_set1_ps(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < w; i++) | |||
| { | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| } | |||
| float* ptr = (float*)bottom_top_blob + i * 8; | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| } | |||
| } | |||
| } | |||
| if (dims == 2) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| if (dims == 2) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| float* ptr = bottom_top_blob.row(i); | |||
| __m256 _slope = num_slope > 1 ? _mm256_loadu_ps((const float*)slope_data + i * 8) : _mm256_set1_ps(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int i = 0; i < h; i++) | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| float* ptr = bottom_top_blob.row(i); | |||
| __m256 _slope = num_slope > 1 ? _mm256_loadu_ps((const float*)slope_data + i * 8) : _mm256_set1_ps(slope_data[0]); | |||
| for (int j = 0; j < w; j++) | |||
| { | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| ptr += 8; | |||
| } | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| ptr += 8; | |||
| } | |||
| } | |||
| } | |||
| if (dims == 3) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| if (dims == 3) | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| { | |||
| int w = bottom_top_blob.w; | |||
| int h = bottom_top_blob.h; | |||
| int channels = bottom_top_blob.c; | |||
| int size = w * h; | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| __m256 _slope = num_slope > 1 ? _mm256_loadu_ps((const float*)slope_data + q * 8) : _mm256_set1_ps(slope_data[0]); | |||
| #pragma omp parallel for num_threads(opt.num_threads) | |||
| for (int q = 0; q < channels; q++) | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| float* ptr = bottom_top_blob.channel(q); | |||
| __m256 _slope = num_slope > 1 ? _mm256_loadu_ps((const float*)slope_data + q * 8) : _mm256_set1_ps(slope_data[0]); | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| ptr += 8; | |||
| } | |||
| __m256 _p = _mm256_loadu_ps(ptr); | |||
| _mm256_storeu_ps(ptr, prelu_avx(_p, _slope)); | |||
| ptr += 8; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| } // opt.use_packing_layout | |||
| return 0; | |||
| } | |||
| #endif // __AVX__ | |||
| if (dims != 3) | |||