Browse Source

prelu pack4 arm neon

tags/20190908
nihuini 7 years ago
parent
commit
77dc3f024d
1 changed files with 106 additions and 0 deletions
  1. +106
    -0
      src/layer/arm/prelu_arm.cpp

+ 106
- 0
src/layer/arm/prelu_arm.cpp View File

@@ -25,6 +25,112 @@ DEFINE_LAYER_CREATOR(PReLU_arm)
int PReLU_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const
{
int dims = bottom_top_blob.dims;
int elempack = bottom_top_blob.elempack;

if (opt.use_packing_layout)
{

if (elempack == 4)
{
float32x4_t _zero = vdupq_n_f32(0.f);

if (dims == 1)
{
int w = bottom_top_blob.w;

float* ptr = bottom_top_blob;

if (num_slope > 1)
{
const float* slope = slope_data;

#pragma omp parallel for num_threads(opt.num_threads)
for (int i=0; i<w; i++)
{
float32x4_t _p = vld1q_f32(ptr);
float32x4_t _slope = vld1q_f32(slope);
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;
slope += 4;
}
}
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 _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 == 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++)
{
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;
}
}
}

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;

#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 _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;
}
}
}

return 0;
}

} // opt.use_packing_layout

if (dims != 3)
return PReLU::forward_inplace(bottom_top_blob, opt);



Loading…
Cancel
Save