Browse Source

packing layout option respect support_packing property

tags/20200727
nihui 6 years ago
parent
commit
01b8b79ed2
17 changed files with 442 additions and 480 deletions
  1. +12
    -16
      src/layer/arm/absval_arm.cpp
  2. +50
    -54
      src/layer/arm/batchnorm_arm.cpp
  3. +5
    -7
      src/layer/arm/concat_arm.cpp
  4. +9
    -9
      src/layer/arm/convolution_arm.cpp
  5. +7
    -7
      src/layer/arm/convolutiondepthwise_arm.cpp
  6. +3
    -3
      src/layer/arm/deconvolution_arm.cpp
  7. +4
    -4
      src/layer/arm/deconvolutiondepthwise_arm.cpp
  8. +39
    -43
      src/layer/arm/dropout_arm.cpp
  9. +71
    -75
      src/layer/arm/prelu_arm.cpp
  10. +93
    -97
      src/layer/arm/scale_arm.cpp
  11. +5
    -7
      src/layer/arm/slice_arm.cpp
  12. +36
    -40
      src/layer/arm/unaryop_arm.cpp
  13. +5
    -7
      src/layer/x86/concat_x86.cpp
  14. +6
    -6
      src/layer/x86/convolution_x86.cpp
  15. +4
    -4
      src/layer/x86/convolutiondepthwise_x86.cpp
  16. +39
    -43
      src/layer/x86/dropout_x86.cpp
  17. +54
    -58
      src/layer/x86/prelu_x86.cpp

+ 12
- 16
src/layer/arm/absval_arm.cpp View File

@@ -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)


+ 50
- 54
src/layer/arm/batchnorm_arm.cpp View File

@@ -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)


+ 5
- 7
src/layer/arm/concat_arm.cpp View File

@@ -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



+ 9
- 9
src/layer/arm/convolution_arm.cpp View File

@@ -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);
// }


+ 7
- 7
src/layer/arm/convolutiondepthwise_arm.cpp View File

@@ -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;


+ 3
- 3
src/layer/arm/deconvolution_arm.cpp View File

@@ -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;


+ 4
- 4
src/layer/arm/deconvolutiondepthwise_arm.cpp View File

@@ -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;


+ 39
- 43
src/layer/arm/dropout_arm.cpp View File

@@ -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);


+ 71
- 75
src/layer/arm/prelu_arm.cpp View File

@@ -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)


+ 93
- 97
src/layer/arm/scale_arm.cpp View File

@@ -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)


+ 5
- 7
src/layer/arm/slice_arm.cpp View File

@@ -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



+ 36
- 40
src/layer/arm/unaryop_arm.cpp View File

@@ -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);


+ 5
- 7
src/layer/x86/concat_x86.cpp View File

@@ -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__



+ 6
- 6
src/layer/x86/convolution_x86.cpp View File

@@ -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)
{


+ 4
- 4
src/layer/x86/convolutiondepthwise_x86.cpp View File

@@ -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;


+ 39
- 43
src/layer/x86/dropout_x86.cpp View File

@@ -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);


+ 54
- 58
src/layer/x86/prelu_x86.cpp View File

@@ -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)


Loading…
Cancel
Save