!5202 [MS][LITE][Develop]fp16 pooling optimize

Merge pull request !5202 from ling/sr
This commit is contained in:
mindspore-ci-bot 2020-08-31 14:40:17 +08:00 committed by Gitee
commit 572c8fa22f
8 changed files with 145 additions and 845 deletions

View File

@ -1,103 +0,0 @@
#ifdef __aarch64__
.text
.align 5
//.p2align 5,,15
.global MatrixAdd
#ifndef __APPLE__
.type MatrixAdd, %function
#endif
//void MatrixAdd(const float* matDataA, const float* matDataB, float* matDataC,
// size_t aStride, size_t bStride, size_t cStride, size_t width, size_t height)
//Auto: x0: matDataA, x1:matDataB, x2:matDatac,
//x3:aStride, x4:bStride, x5:cStride, x6:width, x7:height
MatrixAdd:
mov x12, #4 //sizeof(float)
mul x3, x12, x3
mul x4, x12, x4
mul x5, x12, x5
loopH:
mov x8, x0
mov x9, x1
mov x10, x2
mov x11, x6
loop16LineIn:
cmp x11, #4
blt L8
sub x11, x11, #4
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
fadd v4.4s, v0.4s, v2.4s
fadd v5.4s, v1.4s, v3.4s
ld1 {v6.4s, v7.4s}, [x0], #32
ld1 {v8.4s, v9.4s}, [x1], #32
cmp x11, #4
blt loop16LineOut
loop16:
st1 {v4.4s, v5.4s}, [x2], #32
fadd v10.4s, v6.4s, v8.4s
fadd v11.4s, v7.4s, v9.4s
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
st1 {v10.4s, v11.4s}, [x2], #32
fadd v4.4s, v0.4s, v2.4s
fadd v5.4s, v1.4s, v3.4s
ld1 {v6.4s, v7.4s}, [x0], #32
ld1 {v8.4s, v9.4s}, [x1], #32
sub x11, x11, #4
cmp x11, #4
bge loop16
loop16LineOut:
st1 {v4.4s, v5.4s}, [x2], #32
fadd v10.4s, v6.4s, v8.4s
fadd v11.4s, v7.4s, v9.4s
st1 {v10.4s, v11.4s}, [x2], #32
L8:
cmp x11, #2
blt L4
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
fadd v4.4s, v0.4s, v2.4s
fadd v5.4s, v1.4s, v3.4s
sub x11, x11, #2
st1 {v4.4s, v5.4s}, [x2], #32
cmp x11, #0
beq loop16EndLine
L4:
ld1 {v0.4s}, [x0], #16
ld1 {v1.4s}, [x1], #16
fadd v0.4s, v0.4s, v1.4s
sub x11, x11, #1
st1 {v0.4s}, [x2], #16
//bne L4
loop16EndLine:
add x0, x8, x3
add x1, x9, x4
add x2, x10, x5
subs x7, x7, #1
bne loopH
ret
#endif

View File

@ -1,105 +0,0 @@
#ifdef __aarch64__
.text
.align 5
//.p2align 5,,15
.global MatrixSub
#ifndef __APPLE__
.type MatrixSub, %function
#endif
//void MatrixSub(const float* matDataA, const float* matDataB, float* matDataC,
// size_t aStride, size_t bStride, size_t cStride, size_t width, size_t height)
//Auto: x0: matDataA, x1:matDataB, x2:matDatac,
//x3:aStride, x4:bStride, x5:cStride, x6:width, x7:height
MatrixSub:
mov x12, #4 //sizeof(float)
mul x3, x12, x3
mul x4, x12, x4
mul x5, x12, x5
loopH:
mov x8, x0
mov x9, x1
mov x10, x2
mov x11, x6
loop16LineIn:
cmp x11, #4
blt L8
sub x11, x11, #4
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
fsub v4.4s, v0.4s, v2.4s
fsub v5.4s, v1.4s, v3.4s
ld1 {v6.4s, v7.4s}, [x0], #32
ld1 {v8.4s, v9.4s}, [x1], #32
cmp x11, #4
blt loop16LineOut
loop16:
st1 {v4.4s, v5.4s}, [x2], #32
fsub v10.4s, v6.4s, v8.4s
fsub v11.4s, v7.4s, v9.4s
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
st1 {v10.4s, v11.4s}, [x2], #32
fsub v4.4s, v0.4s, v2.4s
fsub v5.4s, v1.4s, v3.4s
ld1 {v6.4s, v7.4s}, [x0], #32
ld1 {v8.4s, v9.4s}, [x1], #32
sub x11, x11, #4
cmp x11, #4
bge loop16
loop16LineOut:
st1 {v4.4s, v5.4s}, [x2], #32
fsub v10.4s, v6.4s, v8.4s
fsub v11.4s, v7.4s, v9.4s
st1 {v10.4s, v11.4s}, [x2], #32
L8:
cmp x11, #2
blt L4
ld1 {v0.4s, v1.4s}, [x0], #32
ld1 {v2.4s, v3.4s}, [x1], #32
fsub v4.4s, v0.4s, v2.4s
fsub v5.4s, v1.4s, v3.4s
sub x11, x11, #2
st1 {v4.4s, v5.4s}, [x2], #32
cmp x11, #0
beq loop16EndLine
L4:
ld1 {v0.4s}, [x0], #16
ld1 {v1.4s}, [x1], #16
fsub v0.4s, v0.4s, v1.4s
sub x11, x11, #1
st1 {v0.4s}, [x2], #16
loop16EndLine:
add x0, x8, x3
add x1, x9, x4
add x2, x10, x5
subs x7, x7, #1
bne loopH
ret
#endif

View File

@ -51,6 +51,12 @@ void AvgPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
int out_plane_offset = out_batch_offset + index * channel;
int real_win_h_start = MSMAX(0, -in_h_index);
int real_win_h_end = MSMIN(win_h, in_h - in_h_index);
int resl_win_w_start = MSMAX(0, -in_w_index);
int real_win_w_end = MSMIN(win_w, in_w - in_w_index);
for (int j = 0; j < c8; j++) {
int in_channel_offset = in_batch_offset + j * C8NUM;
int out_channel_offset = out_plane_offset + j * C8NUM;
@ -60,22 +66,17 @@ void AvgPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
float16_t tmp_avg[8]{0};
#endif
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_avg = vaddq_f16(tmp_avg, vld1q_f16(input_ptr + in_offset));
tmp_avg = vaddq_f16(tmp_avg, vld1q_f16(input_ptr + in_offset));
#else
for (int t = 0; t < 8; t++) {
tmp_avg[t] += *(input_ptr + in_offset + t);
}
#endif
++real_count;
for (int t = 0; t < 8; t++) {
tmp_avg[t] += *(input_ptr + in_offset + t);
}
#endif
++real_count;
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
@ -97,22 +98,17 @@ void AvgPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
float16_t tmp_avg[4]{0};
#endif
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_avg = vadd_f16(tmp_avg, vld1_f16(input_ptr + in_offset));
tmp_avg = vadd_f16(tmp_avg, vld1_f16(input_ptr + in_offset));
#else
for (int j = 0; j < C4NUM; ++j) {
tmp_avg[j] += *(input_ptr + in_offset);
}
#endif
++real_count;
for (int j = 0; j < C4NUM; ++j) {
tmp_avg[j] += *(input_ptr + in_offset);
}
#endif
++real_count;
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
@ -130,16 +126,11 @@ void AvgPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
int out_channel_offset = out_plane_offset + k;
float16_t tmp_avg = 0;
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += *(input_ptr + in_offset);
++real_count;
}
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += *(input_ptr + in_offset);
++real_count;
} // win_w loop
} // win_h loop
*(output_ptr + out_channel_offset) = tmp_avg / (float16_t)real_count;
@ -148,7 +139,6 @@ void AvgPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
} // out_plane loop
} // out_batch loop
}
void MaxPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingParameter *pooling_param, int task_id) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
@ -183,6 +173,12 @@ void MaxPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
int out_plane_offset = out_batch_offset + index * channel;
int real_win_h_start = MSMAX(0, -in_h_index);
int real_win_h_end = MSMIN(win_h, in_h - in_h_index);
int resl_win_w_start = MSMAX(0, -in_w_index);
int real_win_w_end = MSMIN(win_w, in_w - in_w_index);
for (int j = 0; j < c8; j++) {
int in_channel_offset = in_batch_offset + j * C8NUM;
int out_channel_offset = out_plane_offset + j * C8NUM;
@ -191,21 +187,16 @@ void MaxPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
#else
float16_t tmp_max[8]{-FLT_MAX};
#endif
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_max = vmaxq_f16(tmp_max, vld1q_f16(input_ptr + in_offset));
tmp_max = vmaxq_f16(tmp_max, vld1q_f16(input_ptr + in_offset));
#else
for (int k = 0; k < C8NUM; k++) {
tmp_max[k] = fmax(tmp_max[k], *(input_ptr + in_offset + k));
}
#endif
for (int k = 0; k < C8NUM; k++) {
tmp_max[k] = fmax(tmp_max[k], *(input_ptr + in_offset + k));
}
#endif
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
@ -226,21 +217,16 @@ void MaxPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
#else
float16_t tmp_max[4]{-FLT_MAX};
#endif
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_max = vmax_f16(tmp_max, vld1_f16(input_ptr + in_offset));
tmp_max = vmax_f16(tmp_max, vld1_f16(input_ptr + in_offset));
#else
for (int k = 0; k < C4NUM; k++) {
tmp_max[k] = fmax(tmp_max[k], *(input_ptr + in_offset + k));
}
#endif
for (int k = 0; k < C4NUM; k++) {
tmp_max[k] = fmax(tmp_max[k], *(input_ptr + in_offset + k));
}
#endif
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
@ -257,15 +243,10 @@ void MaxPoolingFp16(const float16_t *input_ptr, float16_t *output_ptr, PoolingPa
int in_channel_offset = in_batch_offset + k;
int out_channel_offset = out_plane_offset + k;
float16_t tmp_max = -FLT_MAX;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_max = fmax(tmp_max, *(input_ptr + in_offset));
}
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_max = fmax(tmp_max, *(input_ptr + in_offset));
} // win_w loop
} // win_h loop
*(output_ptr + out_channel_offset) = tmp_max;

View File

@ -15,54 +15,6 @@
*/
#include "nnacl/fp32/common_func.h"
#ifndef ENABLE_ARM64
void MatrixAdd(const float *a_ptr, const float *b_ptr, float *dst, size_t a_stride, size_t b_stride, size_t c_stride,
size_t row, size_t col) {
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
int a_index = c * a_stride + r * C4NUM;
int b_index = c * b_stride + r * C4NUM;
int c_index = c * c_stride + r * C4NUM;
for (int i = 0; i < C4NUM; i++) {
dst[c_index + i] = a_ptr[a_index + i] + b_ptr[b_index + i];
}
}
}
return;
}
void MatrixSub(const float *a_ptr, const float *b_ptr, float *dst, size_t a_stride, size_t b_stride, size_t c_stride,
size_t row, size_t col) {
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
int a_index = c * a_stride + r * C4NUM;
int b_index = c * b_stride + r * C4NUM;
int c_index = c * c_stride + r * C4NUM;
for (int i = 0; i < C4NUM; i++) {
dst[c_index + i] = a_ptr[a_index + i] - b_ptr[b_index + i];
}
}
}
return;
}
#endif
void MatrixMultiAdd(float *c11, float *c12, float *c21, float *c22, float *x_ptr, size_t row, size_t col,
size_t c_stride, size_t x_stride) {
/* U2 = P1 + P6 */
MatrixAdd(x_ptr, c12, c12, x_stride, c_stride, c_stride, row, col);
/* U3 = U2 + P7 */
MatrixAdd(c12, c21, c21, c_stride, c_stride, c_stride, row, col);
/* U4 = U2 + P5 */
MatrixAdd(c12, c22, c12, c_stride, c_stride, c_stride, row, col);
/* U7 = U3 + P5 */
MatrixAdd(c21, c22, c22, c_stride, c_stride, c_stride, row, col);
/* U5 = U4 + P3 */
MatrixAdd(c12, c11, c12, c_stride, c_stride, c_stride, row, col);
return;
}
void PostConvFuncComm(const float *src_ptr_, float *out_ptr, const float *bias_ptr, size_t output_channel,
size_t plane_size, size_t stride, bool is_relu, bool is_relu6, int size) {
for (int oc = 0; oc < output_channel; oc++) {

View File

@ -31,12 +31,6 @@ void PostConvFuncFp32C4(const float *c4_out_ptr, float *out_ptr, const float *bi
size_t plane_size, size_t stride, bool is_relu, bool is_relu6);
void PostConvFuncFp32C8(const float *c8_out_ptr, float *out_ptr, const float *bias_ptr, size_t output_channel,
size_t plane_size, size_t stride, bool is_relu, bool is_relu6);
void MatrixAdd(const float *a_ptr, const float *b_ptr, float *dst, size_t a_stride, size_t b_stride, size_t c_stride,
size_t row, size_t col);
void MatrixSub(const float *a_ptr, const float *b_ptr, float *dst, size_t a_stride, size_t b_stride, size_t c_stride,
size_t row, size_t col);
void MatrixMultiAdd(float *c11, float *c12, float *c21, float *c22, float *x_ptr, size_t row, size_t col,
size_t c_stride, size_t x_stride);
float ShortToFloat32(uint16_t srcValue);
uint16_t Float32ToShort(float srcValue);

View File

@ -17,7 +17,8 @@
#include "nnacl/fp32/pooling.h"
#include <float.h>
void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id, float minf,
float maxf) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
@ -25,7 +26,7 @@ void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *poo
int win_w = pooling_param->window_w_;
int win_h = pooling_param->window_h_;
int channel = pooling_param->input_channel_;
int c4 = UP_DIV(channel, C4NUM);
int c4 = UP_DIV(channel, C4NUM); /* oc && ic */
int in_w = pooling_param->input_w_;
int in_h = pooling_param->input_h_;
int output_w = pooling_param->output_w_;
@ -34,11 +35,15 @@ void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *poo
int out_plane = output_w * output_h;
int out_tile_count = UP_DIV(out_plane, TILE_NUM);
int thread_num = pooling_param->thread_num_;
// input channel is equal to output channel
#ifdef ENABLE_NEON
float32x4_t min_value = vdupq_n_f32(minf);
float32x4_t max_value = vdupq_n_f32(maxf);
#endif
for (int batch = 0; batch < output_batch; batch++) {
int in_batch_offset = batch * in_h * in_w * channel;
int out_batch_offset = batch * output_h * output_w * channel;
const float *src_b_ptr = input_ptr + batch * in_h * in_w * channel;
float *dst_b_ptr = output_ptr + batch * output_h * output_w * channel;
for (int thread_id = task_id; thread_id < out_tile_count; thread_id += thread_num) {
int cal_start_index = thread_id * TILE_NUM;
int real_cal_num = (out_plane - cal_start_index) > TILE_NUM ? TILE_NUM : (out_plane - cal_start_index);
@ -48,10 +53,18 @@ void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *poo
int out_h_index = index / output_w;
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
int out_plane_offset = out_batch_offset + index * channel;
for (int j = 0; j < c4 - 1; j++) {
int in_channel_offset = in_batch_offset + j * C4NUM;
int out_channel_offset = out_plane_offset + j * C4NUM;
const float *src_plane_ptr = src_b_ptr;
float *dst_plane_ptr = dst_b_ptr + index * channel;
int real_win_h_start = MSMAX(0, -in_h_index);
int real_win_h_end = MSMIN(win_h, in_h - in_h_index);
int resl_win_w_start = MSMAX(0, -in_w_index);
int real_win_w_end = MSMIN(win_w, in_w - in_w_index);
for (int ci = 0; ci < c4 - 1; ci++) {
const float *src_c_ptr = src_plane_ptr + ci * C4NUM;
float *dst_c_ptr = dst_plane_ptr + ci * C4NUM;
#ifdef ENABLE_NEON
float32x4_t tmp_avg = vdupq_n_f32(0);
#else
@ -61,60 +74,69 @@ void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *poo
float tmp_avg4 = 0;
#endif
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_avg = vaddq_f32(tmp_avg, vld1q_f32(input_ptr + in_offset));
tmp_avg = vaddq_f32(tmp_avg, vld1q_f32(src_win_ptr));
#else
tmp_avg1 += *(input_ptr + in_offset);
tmp_avg2 += *(input_ptr + in_offset + 1);
tmp_avg3 += *(input_ptr + in_offset + 2);
tmp_avg4 += *(input_ptr + in_offset + 3);
tmp_avg1 += src_win_ptr[0];
tmp_avg2 += src_win_ptr[1];
tmp_avg3 += src_win_ptr[2];
tmp_avg4 += src_win_ptr[3];
#endif
++real_count;
}
++real_count;
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
vst1q_f32(output_ptr + out_channel_offset, tmp_avg / vdupq_n_f32(real_count));
tmp_avg = tmp_avg / vdupq_n_f32(real_count);
tmp_avg = vmaxq_f32(tmp_avg, min_value);
tmp_avg = vminq_f32(tmp_avg, max_value);
vst1q_f32(dst_c_ptr, tmp_avg);
#else
*(output_ptr + out_channel_offset) = tmp_avg1 / (float)real_count;
*(output_ptr + out_channel_offset + 1) = tmp_avg2 / (float)real_count;
*(output_ptr + out_channel_offset + 2) = tmp_avg3 / (float)real_count;
*(output_ptr + out_channel_offset + 3) = tmp_avg4 / (float)real_count;
tmp_avg1 /= (float)real_count;
tmp_avg2 /= (float)real_count;
tmp_avg3 /= (float)real_count;
tmp_avg4 /= (float)real_count;
tmp_avg1 = fmax(tmp_avg1, minf);
tmp_avg2 = fmax(tmp_avg2, minf);
tmp_avg3 = fmax(tmp_avg3, minf);
tmp_avg4 = fmax(tmp_avg4, minf);
tmp_avg1 = fmin(tmp_avg1, maxf);
tmp_avg2 = fmin(tmp_avg2, maxf);
tmp_avg3 = fmin(tmp_avg3, maxf);
tmp_avg4 = fmin(tmp_avg4, maxf);
dst_c_ptr[0] = tmp_avg1;
dst_c_ptr[1] = tmp_avg2;
dst_c_ptr[2] = tmp_avg3;
dst_c_ptr[3] = tmp_avg4;
#endif
} // ic4-1 loop
int channel_s = (c4 - 1) * C4NUM;
for (int k = channel_s; k < channel; k++) {
int in_channel_offset = in_batch_offset + k;
int out_channel_offset = out_plane_offset + k;
for (int ci = channel_s; ci < channel; ci++) {
const float *src_c_ptr = src_plane_ptr + ci;
float *dst_c_ptr = dst_plane_ptr + ci;
float tmp_avg = 0;
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += *(input_ptr + in_offset);
++real_count;
}
for (int h = real_win_h_start; h < real_win_h_end; h++) {
for (int w = resl_win_w_start; w < real_win_w_end; w++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += src_win_ptr[0];
++real_count;
} // win_w loop
} // win_h loop
*(output_ptr + out_channel_offset) = tmp_avg / (float)real_count;
tmp_avg = tmp_avg / (float)real_count;
tmp_avg = fmax(tmp_avg, minf);
tmp_avg = fmin(tmp_avg, maxf);
dst_c_ptr[0] = tmp_avg;
} // channel_res loop
} // real_cal_num loop
} // out_plane loop
} // out_batch loop
}
void MaxPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
void MaxPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id, float minf,
float maxf) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
@ -132,207 +154,9 @@ void MaxPooling(const float *input_ptr, float *output_ptr, PoolingParameter *poo
int thread_num = pooling_param->thread_num_;
int c4 = UP_DIV(channel, C4NUM); /* oc && ic */
for (int batch = 0; batch < output_batch; batch++) {
const float *src_b_ptr = input_ptr + batch * in_h * in_w * channel;
float *dst_b_ptr = output_ptr + batch * output_h * output_w * channel;
for (int thread_id = task_id; thread_id < out_tile_count; thread_id += thread_num) {
int cal_start_index = thread_id * TILE_NUM;
int real_cal_num = (out_plane - cal_start_index) > TILE_NUM ? TILE_NUM : (out_plane - cal_start_index);
for (int i = 0; i < real_cal_num; i++) {
int index = cal_start_index + i;
int out_w_index = index % output_w;
int out_h_index = index / output_w;
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
const float *src_plane_ptr = src_b_ptr;
float *dst_plane_ptr = dst_b_ptr + index * channel;
int real_win_h_start = MSMAX(0, -in_h_index);
int real_win_h_end = MSMIN(win_h, in_h - in_h_index);
int resl_win_w_start = MSMAX(0, -in_w_index);
int real_win_w_end = MSMIN(win_w, in_w - in_w_index);
for (int ci = 0; ci < c4 - 1; ci++) {
const float *src_c_ptr = src_plane_ptr + ci * C4NUM;
float *dst_c_ptr = dst_plane_ptr + ci * C4NUM;
#ifdef ENABLE_NEON
float32x4_t tmp_max = vdupq_n_f32(-FLT_MAX);
#else
float tmp_max1 = -FLT_MAX;
float tmp_max2 = -FLT_MAX;
float tmp_max3 = -FLT_MAX;
float tmp_max4 = -FLT_MAX;
#endif
for (int kh = real_win_h_start; kh < real_win_h_end; kh++) {
for (int kw = resl_win_w_start; kw < real_win_w_end; kw++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + kh) * in_w + in_w_index + kw) * channel;
#ifdef ENABLE_NEON
tmp_max = vmaxq_f32(tmp_max, vld1q_f32(src_win_ptr));
#else
tmp_max1 = fmax(tmp_max1, src_win_ptr[0]);
tmp_max2 = fmax(tmp_max2, src_win_ptr[1]);
tmp_max3 = fmax(tmp_max3, src_win_ptr[2]);
tmp_max4 = fmax(tmp_max4, src_win_ptr[3]);
#endif
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
vst1q_f32(dst_c_ptr, tmp_max);
#else
dst_c_ptr[0] = tmp_max1;
dst_c_ptr[1] = tmp_max2;
dst_c_ptr[2] = tmp_max3;
dst_c_ptr[3] = tmp_max4;
#endif
} // ic4-1 loop
int channel_s = (c4 - 1) * C4NUM;
for (int ci = channel_s; ci < channel; ci++) {
float *dst_c_ptr = dst_plane_ptr + ci;
const float *src_c_ptr = src_plane_ptr + ci;
float tmp_max = -FLT_MAX;
for (int kh = real_win_h_start; kh < real_win_h_end; kh++) {
for (int kw = resl_win_w_start; kw < real_win_w_end; kw++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + kh) * in_w + in_w_index + kw) * channel;
tmp_max = fmax(tmp_max, src_win_ptr[0]);
} // win_w loop
} // win_h loop
dst_c_ptr[0] = tmp_max;
} // channel_res loop
} // real_cal_num loop
} // out_plane loop
} // out_batch loop
}
void AvgPoolingRelu(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
int pad_h = pooling_param->pad_u_;
int win_w = pooling_param->window_w_;
int win_h = pooling_param->window_h_;
int channel = pooling_param->input_channel_;
int c4 = UP_DIV(channel, C4NUM);
int in_w = pooling_param->input_w_;
int in_h = pooling_param->input_h_;
int output_w = pooling_param->output_w_;
int output_h = pooling_param->output_h_;
int output_batch = pooling_param->output_batch_;
int out_plane = output_w * output_h;
int out_tile_count = UP_DIV(out_plane, TILE_NUM);
int thread_num = pooling_param->thread_num_;
#ifdef ENABLE_NEON
float32x4_t zeros = vdupq_n_f32(0);
#endif
for (int batch = 0; batch < output_batch; batch++) {
int in_batch_offset = batch * in_h * in_w * channel;
int out_batch_offset = batch * output_h * output_w * channel;
for (int thread_id = task_id; thread_id < out_tile_count; thread_id += thread_num) {
int cal_start_index = thread_id * TILE_NUM;
int real_cal_num = (out_plane - cal_start_index) > TILE_NUM ? TILE_NUM : (out_plane - cal_start_index);
for (int i = 0; i < real_cal_num; i++) {
int index = cal_start_index + i;
int out_w_index = index % output_w;
int out_h_index = index / output_w;
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
int out_plane_offset = out_batch_offset + index * channel;
for (int j = 0; j < c4 - 1; j++) {
int in_channel_offset = in_batch_offset + j * C4NUM;
int out_channel_offset = out_plane_offset + j * C4NUM;
#ifdef ENABLE_NEON
float32x4_t tmp_avg = vdupq_n_f32(0);
#else
float tmp_avg1 = 0;
float tmp_avg2 = 0;
float tmp_avg3 = 0;
float tmp_avg4 = 0;
#endif
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_avg = vaddq_f32(tmp_avg, vld1q_f32(input_ptr + in_offset));
#else
tmp_avg1 += *(input_ptr + in_offset);
tmp_avg2 += *(input_ptr + in_offset + 1);
tmp_avg3 += *(input_ptr + in_offset + 2);
tmp_avg4 += *(input_ptr + in_offset + 3);
#endif
++real_count;
}
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
tmp_avg = vmaxq_f32(tmp_avg, zeros);
vst1q_f32(output_ptr + out_channel_offset, tmp_avg / vdupq_n_f32(real_count));
#else
tmp_avg1 = fmax(tmp_avg1, 0);
tmp_avg2 = fmax(tmp_avg2, 0);
tmp_avg3 = fmax(tmp_avg3, 0);
tmp_avg4 = fmax(tmp_avg4, 0);
*(output_ptr + out_channel_offset) = tmp_avg1 / (float)real_count;
*(output_ptr + out_channel_offset + 1) = tmp_avg2 / (float)real_count;
*(output_ptr + out_channel_offset + 2) = tmp_avg3 / (float)real_count;
*(output_ptr + out_channel_offset + 3) = tmp_avg4 / (float)real_count;
#endif
} // ic4-1 loop
int channel_s = (c4 - 1) * C4NUM;
for (int k = channel_s; k < channel; k++) {
int in_channel_offset = in_batch_offset + k;
int out_channel_offset = out_plane_offset + k;
float tmp_avg = 0;
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += *(input_ptr + in_offset);
++real_count;
}
} // win_w loop
} // win_h loop
tmp_avg = fmax(tmp_avg, 0);
*(output_ptr + out_channel_offset) = tmp_avg / (float)real_count;
} // channel_res loop
} // real_cal_num loop
} // out_plane loop
} // out_batch loop
}
void MaxPoolingRelu(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
int pad_h = pooling_param->pad_u_;
int win_w = pooling_param->window_w_;
int win_h = pooling_param->window_h_;
int channel = pooling_param->input_channel_;
int in_w = pooling_param->input_w_;
int in_h = pooling_param->input_h_;
int output_w = pooling_param->output_w_;
int output_h = pooling_param->output_h_;
int output_batch = pooling_param->output_batch_;
int out_plane = output_w * output_h;
int out_tile_count = UP_DIV(out_plane, TILE_NUM);
int thread_num = pooling_param->thread_num_;
int c4 = UP_DIV(channel, C4NUM);
#ifdef ENABLE_NEON
float32x4_t zeros = vdupq_n_f32(0);
float32x4_t min_value = vdupq_n_f32(minf);
float32x4_t max_value = vdupq_n_f32(maxf);
#endif
for (int batch = 0; batch < output_batch; batch++) {
@ -378,251 +202,22 @@ void MaxPoolingRelu(const float *input_ptr, float *output_ptr, PoolingParameter
tmp_max2 = fmax(tmp_max2, src_win_ptr[1]);
tmp_max3 = fmax(tmp_max3, src_win_ptr[2]);
tmp_max4 = fmax(tmp_max4, src_win_ptr[3]);
#endif
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
tmp_max = vmaxq_f32(tmp_max, zeros);
tmp_max = vmaxq_f32(tmp_max, min_value);
tmp_max = vminq_f32(tmp_max, max_value);
vst1q_f32(dst_c_ptr, tmp_max);
#else
// relu:
tmp_max1 = fmax(tmp_max1, 0);
tmp_max2 = fmax(tmp_max2, 0);
tmp_max3 = fmax(tmp_max3, 0);
tmp_max4 = fmax(tmp_max4, 0);
dst_c_ptr[0] = tmp_max1;
dst_c_ptr[1] = tmp_max2;
dst_c_ptr[2] = tmp_max3;
dst_c_ptr[3] = tmp_max4;
#endif
} // ic4-1 loop
int channel_s = (c4 - 1) * C4NUM;
for (int ci = channel_s; ci < channel; ci++) {
float *dst_c_ptr = dst_plane_ptr + ci;
const float *src_c_ptr = src_plane_ptr + ci;
float tmp_max = -FLT_MAX;
for (int kh = real_win_h_start; kh < real_win_h_end; kh++) {
for (int kw = resl_win_w_start; kw < real_win_w_end; kw++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + kh) * in_w + in_w_index + kw) * channel;
tmp_max = fmax(tmp_max, src_win_ptr[0]);
} // win_w loop
} // win_h loop
dst_c_ptr[0] = tmp_max;
} // channel_res loop
} // real_cal_num loop
} // out_plane loop
} // out_batch loop
}
void AvgPoolingRelu6(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
int pad_h = pooling_param->pad_u_;
int win_w = pooling_param->window_w_;
int win_h = pooling_param->window_h_;
int channel = pooling_param->input_channel_;
int c4 = UP_DIV(channel, C4NUM);
int in_w = pooling_param->input_w_;
int in_h = pooling_param->input_h_;
int output_w = pooling_param->output_w_;
int output_h = pooling_param->output_h_;
int output_batch = pooling_param->output_batch_;
int out_plane = output_w * output_h;
int out_tile_count = UP_DIV(out_plane, TILE_NUM);
int thread_num = pooling_param->thread_num_;
// input channel is equal to output channel
#ifdef ENABLE_NEON
float32x4_t zeros = vdupq_n_f32(0);
float32x4_t bounds = vdupq_n_f32(6);
#endif
for (int batch = 0; batch < output_batch; batch++) {
int in_batch_offset = batch * in_h * in_w * channel;
int out_batch_offset = batch * output_h * output_w * channel;
for (int thread_id = task_id; thread_id < out_tile_count; thread_id += thread_num) {
int cal_start_index = thread_id * TILE_NUM;
int real_cal_num = (out_plane - cal_start_index) > TILE_NUM ? TILE_NUM : (out_plane - cal_start_index);
for (int i = 0; i < real_cal_num; i++) {
int index = cal_start_index + i;
int out_w_index = index % output_w;
int out_h_index = index / output_w;
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
int out_plane_offset = out_batch_offset + index * channel;
for (int j = 0; j < c4 - 1; j++) {
int in_channel_offset = in_batch_offset + j * C4NUM;
int out_channel_offset = out_plane_offset + j * C4NUM;
#ifdef ENABLE_NEON
float32x4_t tmp_avg = vdupq_n_f32(0);
#else
float tmp_avg1 = 0;
float tmp_avg2 = 0;
float tmp_avg3 = 0;
float tmp_avg4 = 0;
#endif
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
#ifdef ENABLE_NEON
tmp_avg = vaddq_f32(tmp_avg, vld1q_f32(input_ptr + in_offset));
#else
tmp_avg1 += *(input_ptr + in_offset);
tmp_avg2 += *(input_ptr + in_offset + 1);
tmp_avg3 += *(input_ptr + in_offset + 2);
tmp_avg4 += *(input_ptr + in_offset + 3);
#endif
++real_count;
}
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
tmp_avg = tmp_avg / vdupq_n_f32(real_count);
tmp_avg = vmaxq_f32(tmp_avg, zeros);
tmp_avg = vminq_f32(tmp_avg, bounds);
vst1q_f32(output_ptr + out_channel_offset, tmp_avg);
#else
tmp_avg1 /= (float)real_count;
tmp_avg2 /= (float)real_count;
tmp_avg3 /= (float)real_count;
tmp_avg4 /= (float)real_count;
tmp_avg1 = fmax(tmp_avg1, 0);
tmp_avg2 = fmax(tmp_avg2, 0);
tmp_avg3 = fmax(tmp_avg3, 0);
tmp_avg4 = fmax(tmp_avg4, 0);
tmp_avg1 = fmin(tmp_avg1, 6);
tmp_avg2 = fmin(tmp_avg2, 6);
tmp_avg3 = fmin(tmp_avg3, 6);
tmp_avg4 = fmin(tmp_avg4, 6);
*(output_ptr + out_channel_offset) = tmp_avg1;
*(output_ptr + out_channel_offset + 1) = tmp_avg2;
*(output_ptr + out_channel_offset + 2) = tmp_avg3;
*(output_ptr + out_channel_offset + 3) = tmp_avg4;
#endif
} // ic4-1 loop
int channel_s = (c4 - 1) * C4NUM;
for (int k = channel_s; k < channel; k++) {
int in_channel_offset = in_batch_offset + k;
int out_channel_offset = out_plane_offset + k;
float tmp_avg = 0;
int real_count = 0;
for (int h = 0; h < win_h; h++) {
for (int w = 0; w < win_w; w++) {
if ((in_h_index + h) < 0 || (in_h_index + h) >= in_h || (in_w_index + w) < 0 ||
(in_w_index + w) >= in_w) {
continue;
} else {
int in_offset = in_channel_offset + ((in_h_index + h) * in_w + in_w_index + w) * channel;
tmp_avg += *(input_ptr + in_offset);
++real_count;
}
} // win_w loop
} // win_h loop
tmp_avg /= (float)real_count;
tmp_avg = fmax(tmp_avg, 0);
tmp_avg = fmin(tmp_avg, 6);
*(output_ptr + out_channel_offset) = tmp_avg;
} // channel_res loop
} // real_cal_num loop
} // out_plane loop
} // out_batch loop
}
void MaxPoolingRelu6(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id) {
int stride_w = pooling_param->stride_w_;
int stride_h = pooling_param->stride_h_;
int pad_w = pooling_param->pad_l_;
int pad_h = pooling_param->pad_u_;
int win_w = pooling_param->window_w_;
int win_h = pooling_param->window_h_;
int channel = pooling_param->input_channel_;
int in_w = pooling_param->input_w_;
int in_h = pooling_param->input_h_;
int output_w = pooling_param->output_w_;
int output_h = pooling_param->output_h_;
int output_batch = pooling_param->output_batch_;
int out_plane = output_w * output_h;
int out_tile_count = UP_DIV(out_plane, TILE_NUM);
int thread_num = pooling_param->thread_num_;
int c4 = UP_DIV(channel, C4NUM);
#ifdef ENABLE_NEON
float32x4_t zeros = vdupq_n_f32(0);
float32x4_t bounds = vdupq_n_f32(6);
#endif
for (int batch = 0; batch < output_batch; batch++) {
const float *src_b_ptr = input_ptr + batch * in_h * in_w * channel;
float *dst_b_ptr = output_ptr + batch * output_h * output_w * channel;
for (int thread_id = task_id; thread_id < out_tile_count; thread_id += thread_num) {
int cal_start_index = thread_id * TILE_NUM;
int real_cal_num = (out_plane - cal_start_index) > TILE_NUM ? TILE_NUM : (out_plane - cal_start_index);
for (int i = 0; i < real_cal_num; i++) {
int index = cal_start_index + i;
int out_w_index = index % output_w;
int out_h_index = index / output_w;
int in_w_index = out_w_index * stride_w - pad_w;
int in_h_index = out_h_index * stride_h - pad_h;
const float *src_plane_ptr = src_b_ptr;
float *dst_plane_ptr = dst_b_ptr + index * channel;
int real_win_h_start = MSMAX(0, -in_h_index);
int real_win_h_end = MSMIN(win_h, in_h - in_h_index);
int resl_win_w_start = MSMAX(0, -in_w_index);
int real_win_w_end = MSMIN(win_w, in_w - in_w_index);
for (int ci = 0; ci < c4 - 1; ci++) {
const float *src_c_ptr = src_plane_ptr + ci * C4NUM;
float *dst_c_ptr = dst_plane_ptr + ci * C4NUM;
#ifdef ENABLE_NEON
float32x4_t tmp_max = vdupq_n_f32(-FLT_MAX);
#else
float tmp_max1 = -FLT_MAX;
float tmp_max2 = -FLT_MAX;
float tmp_max3 = -FLT_MAX;
float tmp_max4 = -FLT_MAX;
#endif
for (int kh = real_win_h_start; kh < real_win_h_end; kh++) {
for (int kw = resl_win_w_start; kw < real_win_w_end; kw++) {
const float *src_win_ptr = src_c_ptr + ((in_h_index + kh) * in_w + in_w_index + kw) * channel;
#ifdef ENABLE_NEON
tmp_max = vmaxq_f32(tmp_max, vld1q_f32(src_win_ptr));
#else
tmp_max1 = fmax(tmp_max1, src_win_ptr[0]);
tmp_max2 = fmax(tmp_max2, src_win_ptr[1]);
tmp_max3 = fmax(tmp_max3, src_win_ptr[2]);
tmp_max4 = fmax(tmp_max4, src_win_ptr[3]);
#endif
} // win_w loop
} // win_h loop
#ifdef ENABLE_NEON
tmp_max = vmaxq_f32(tmp_max, zeros);
tmp_max = vminq_f32(tmp_max, bounds);
vst1q_f32(dst_c_ptr, tmp_max);
#else
// relu:
tmp_max1 = fmax(tmp_max1, 0);
tmp_max2 = fmax(tmp_max2, 0);
tmp_max3 = fmax(tmp_max3, 0);
tmp_max4 = fmax(tmp_max4, 0);
tmp_max1 = fmin(tmp_max1, 6);
tmp_max2 = fmin(tmp_max2, 6);
tmp_max3 = fmin(tmp_max3, 6);
tmp_max4 = fmin(tmp_max4, 6);
tmp_max1 = fmax(tmp_max1, minf);
tmp_max2 = fmax(tmp_max2, minf);
tmp_max3 = fmax(tmp_max3, minf);
tmp_max4 = fmax(tmp_max4, minf);
tmp_max1 = fmin(tmp_max1, maxf);
tmp_max2 = fmin(tmp_max2, maxf);
tmp_max3 = fmin(tmp_max3, maxf);
tmp_max4 = fmin(tmp_max4, maxf);
dst_c_ptr[0] = tmp_max1;
dst_c_ptr[1] = tmp_max2;
dst_c_ptr[2] = tmp_max3;
@ -641,6 +236,8 @@ void MaxPoolingRelu6(const float *input_ptr, float *output_ptr, PoolingParameter
tmp_max = fmax(tmp_max, src_win_ptr[0]);
} // win_w loop
} // win_h loop
tmp_max = fmax(tmp_max, minf);
tmp_max = fmin(tmp_max, maxf);
dst_c_ptr[0] = tmp_max;
} // channel_res loop
} // real_cal_num loop

View File

@ -27,17 +27,10 @@
#ifdef __cplusplus
extern "C" {
#endif
void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void MaxPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void AvgPoolingRelu(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void MaxPoolingRelu(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void AvgPoolingRelu6(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void MaxPoolingRelu6(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id);
void AvgPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id, float minf,
float maxf);
void MaxPooling(const float *input_ptr, float *output_ptr, PoolingParameter *pooling_param, int task_id, float minf,
float maxf);
#ifdef __cplusplus
}
#endif

View File

@ -15,6 +15,7 @@
*/
#include "src/runtime/kernel/arm/fp32/pooling.h"
#include <float.h>
#include "nnacl/fp32/pooling.h"
#include "src/kernel_registry.h"
#include "src/runtime/runtime_api.h"
@ -52,28 +53,18 @@ int PoolingCPUKernel::ReSize() {
int PoolingCPUKernel::RunImpl(int task_id) {
auto input_ptr = reinterpret_cast<float *>(in_tensors_.at(kInputIndex)->Data());
auto output_ptr = reinterpret_cast<float *>(out_tensors_.at(kOutputIndex)->Data());
float minf = -FLT_MAX;
float maxf = FLT_MAX;
if (pooling_param_->act_type_ == ActType_Relu) {
minf = 0.f;
} else if (pooling_param_->act_type_ == ActType_Relu6) {
minf = 0.f;
maxf = 6.f;
}
if (pooling_param_->pool_mode_ == PoolMode_MaxPool) {
switch (pooling_param_->act_type_) {
case ActType_Relu:
MaxPoolingRelu(input_ptr, output_ptr, pooling_param_, task_id);
break;
case ActType_Relu6:
MaxPoolingRelu6(input_ptr, output_ptr, pooling_param_, task_id);
break;
default:
MaxPooling(input_ptr, output_ptr, pooling_param_, task_id);
}
MaxPooling(input_ptr, output_ptr, pooling_param_, task_id, minf, maxf);
} else {
switch (pooling_param_->act_type_) {
case ActType_Relu:
AvgPoolingRelu(input_ptr, output_ptr, pooling_param_, task_id);
break;
case ActType_Relu6:
AvgPoolingRelu6(input_ptr, output_ptr, pooling_param_, task_id);
break;
default:
AvgPooling(input_ptr, output_ptr, pooling_param_, task_id);
}
AvgPooling(input_ptr, output_ptr, pooling_param_, task_id, minf, maxf);
}
return RET_OK;
}