diff --git a/src/operators/kernel/central-arm-func/conv_arm_func.h b/src/operators/kernel/central-arm-func/conv_arm_func.h index f80a8f944139566483c47daf10f9decac49650dc..e7a8c7f52db327f3ff5871566c3557c484ba4d13 100644 --- a/src/operators/kernel/central-arm-func/conv_arm_func.h +++ b/src/operators/kernel/central-arm-func/conv_arm_func.h @@ -16,7 +16,6 @@ limitations under the License. */ #pragma once #include -#include "operators/math/conv_arm_int8.h" #include "operators/math/conv_func.h" #include "operators/math/depthwise_conv_3x3.h" #include "operators/math/im2col.h" @@ -28,11 +27,12 @@ limitations under the License. */ namespace paddle_mobile { namespace operators { -template +template inline void ConvBasic(const ConvParam ¶m) { const Tensor *input = param.Input(); Tensor filter = *param.Filter(); Tensor *output = param.Output(); + output->mutable_data(); int groups = param.Groups(); const std::vector strides = param.Strides(); const std::vector paddings = param.Paddings(); @@ -60,7 +60,7 @@ inline void ConvBasic(const ConvParam ¶m) { Tensor col; Tensor col_matrix; if (is_expand) { - col.mutable_data(col_shape); + col.mutable_data(col_shape); col_matrix.ShareDataWith(col); col_matrix.Resize(col_matrix_shape); } @@ -79,8 +79,8 @@ inline void ConvBasic(const ConvParam ¶m) { int in_step = static_cast(input->dims()[1]) / groups; int out_step = static_cast(output->dims()[1]) / groups; - math::Vol2ColFunctor vol2col; - math::Im2ColFunctor im2col; + math::Vol2ColFunctor vol2col; + math::Im2ColFunctor im2col; for (int i = 0; i < batch_size; i++) { Tensor in_batch = input->Slice(i, i + 1).Resize(input_shape); @@ -109,69 +109,18 @@ inline void ConvBasic(const ConvParam ¶m) { Tensor out_slice = out_batch.Slice(g * out_step, (g + 1) * out_step); Tensor filter_slice = filter.Slice(g * out_step, (g + 1) * out_step); - math::matmul(filter_slice, false, col_matrix, false, + math::matmul(filter_slice, false, col_matrix, false, static_cast(1), &out_slice, static_cast(0)); } } } -inline void ConvCompute_int8(const ConvParam ¶m) { - typedef void (*ConvFunc)(const Tensor &input, const Tensor &kernel, - Tensor *output); - static ConvFunc conv_funcs_table[7][5] = { - {0, 0, 0, 0, 0}, // k = 1 - {0, 0, 0, 0, 0}, {conv3x3s1_int8, 0, 0, 0, 0}, // k = 3 - {0, 0, 0, 0, 0}, {conv5x5s1_int8, 0, 0, 0, 0}, // k = 5 - {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, // k = 7 - }; - const Tensor *input = param.Input(); - Tensor *filter = param.Filter(); - Tensor *output = param.Output(); - int groups = param.Groups(); - const std::vector &strides = param.Strides(); - const std::vector &paddings = param.Paddings(); - const std::vector &dilations = param.Dilations(); - int kernel_h = filter->dims()[2]; - int kernel_w = filter->dims()[3]; - output->mutable_data(); - - ConvFunc conv_func = 0; - if (strides[1] == strides[0] && strides[1] < 6 && kernel_h == kernel_w && - kernel_h < 8 && groups == 1 && dilations[0] == dilations[1] && - dilations[1] == 1) { - conv_func = conv_funcs_table[kernel_h - 1][strides[0] - 1]; - } - if (conv_func) { - int batch_size = input->dims()[0]; - math::PadFunctor pad; - - Tensor input_pad; - for (int i = 0; i < batch_size; ++i) { - Tensor in_batch = input->Slice(i, i + 1); - Tensor out_batch = output->Slice(i, i + 1); - if (paddings[0] == 0 && paddings[1] == 0) { - input_pad = in_batch; - } else { - framework::DDim pad_shape = in_batch.dims(); - pad_shape[2] += 2 * paddings[0]; - pad_shape[3] += 2 * paddings[1]; - input_pad.mutable_data(pad_shape); - pad(in_batch, paddings[0], paddings[1], &input_pad); - } - conv_func(input_pad, *filter, &out_batch); - } - } else { - ConvBasic(param); - } -} - template void ConvCompute(const ConvParam ¶m) { if (param.Input()->type() == typeid(int8_t)) { - ConvCompute_int8(param); + ConvBasic(param); } else { - param.Output()->mutable_data(); if (param.Groups() == param.Input()->dims()[1] && param.Input()->dims()[1] == param.Output()->dims()[1] && param.Filter()->dims()[2] == param.Filter()->dims()[3] && @@ -185,7 +134,7 @@ void ConvCompute(const ConvParam ¶m) { math::DepthwiseConv3x3(param.Input(), param.Strides(), param.Paddings(), param.Filter(), nullptr, param.Output(), false); } else { - ConvBasic(param); + ConvBasic(param); } } } diff --git a/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h b/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h index ff5d5d4b2a351d075fcecce209063aa66e026754..73170bdab922a46831334307aebc8af210ddfb73 100644 --- a/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h +++ b/src/operators/kernel/central-arm-func/depthwise_conv_arm_func.h @@ -44,7 +44,7 @@ void DepthwiseConvCompute(const ConvParam ¶m) { Bias, false); } else { - ConvBasic(param); + ConvBasic(param); } } diff --git a/src/operators/math/conv3x3_arm_int8.cpp b/src/operators/math/conv3x3_arm_int8.cpp deleted file mode 100644 index 283dcb2255b43052dcaf2d622ad629e923810a82..0000000000000000000000000000000000000000 --- a/src/operators/math/conv3x3_arm_int8.cpp +++ /dev/null @@ -1,761 +0,0 @@ -/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -#ifdef CONV_OP - -#include "operators/math/conv_arm_int8.h" - -namespace paddle_mobile { -namespace operators { - -void conv3x3s1_int8(const framework::Tensor& input, - const framework::Tensor& weight, - framework::Tensor* output) { -#if defined(__ARM_NEON__) || defined(__ARM_NEON) - const int8_t* in_data = input.data(); - const int8_t* w_data = weight.data(); - int32_t* out_data = output->mutable_data(); - // make sure that batch size is 1 - int input_c = input.dims()[1]; - int input_h = input.dims()[2]; - int input_w = input.dims()[3]; - int output_c = output->dims()[1]; - int output_h = output->dims()[2]; - int output_w = output->dims()[3]; - int image_size = input_h * input_w; - int out_image_size = output_h * output_w; - memset(out_data, 0, output_c * out_image_size * sizeof(int32_t)); -#if __aarch64__ - // TODO(hjchen2) -#else - int oc = 0; - #pragma omp parallel for - for (; oc < output_c - 1; oc += 2) { - for (int ic = 0; ic < input_c; ++ic) { - const int8_t* kernel0 = w_data + (oc * input_c + ic) * 9; - const int8_t* kernel1 = w_data + ((oc + 1) * input_c + ic) * 9; - int32_t* output0 = out_data + oc * out_image_size; - int32_t* output0n = output0 + output_w; - int32_t* output1 = out_data + (oc + 1) * out_image_size; - int32_t* output1n = output1 + output_w; - - int oh = 0; - for (; oh < output_h - 1; oh += 2) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - const int8_t* r3 = r2 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - "vld1.8 {d1}, [%[kernel1]] \n" - "ldr r6, [%[kernel1], #8] \n" - - "0: \n" - "vld1.8 {d2-d3}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[0] \n" - "vdup.s8 d7, d0[1] \n" - "vdup.s8 d8, d0[2] \n" - "vdup.s8 d9, d1[0] \n" - "vdup.s8 d10, d1[1] \n" - "vdup.s8 d11, d1[2] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q12, d12, d14 \n" - "vaddl.s16 q13, d13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddl.s16 q14, d12, d14 \n" - "vaddl.s16 q15, d13, d15 \n" - - "vld1.8 {d2-d3}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q8, d12, d14 \n" - "vaddl.s16 q9, d13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddl.s16 q10, d12, d14 \n" - "vaddl.s16 q11, d13, d15 \n" - - "vdup.s8 d6, d0[3] \n" - "vdup.s8 d7, d0[4] \n" - "vdup.s8 d8, d0[5] \n" - "vdup.s8 d9, d1[3] \n" - "vdup.s8 d10, d1[4] \n" - "vdup.s8 d11, d1[5] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q14, q14, d12 \n" - "vaddw.s16 q15, q15, d13 \n" - "vaddw.s16 q14, q14, d14 \n" - "vaddw.s16 q15, q15, d15 \n" - - "vld1.8 {d2-d3}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q8, q8, d12 \n" - "vaddw.s16 q8, q8, d14 \n" - "vaddw.s16 q9, q9, d13 \n" - "vaddw.s16 q9, q9, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q10, q10, d12 \n" - "vaddw.s16 q11, q11, d13 \n" - "vaddw.s16 q10, q10, d14 \n" - "vaddw.s16 q11, q11, d15 \n" - - "vdup.s8 d6, d0[6] \n" - "vdup.s8 d7, d0[7] \n" - "vdup.s8 d8, r5 \n" - "vdup.s8 d9, d1[6] \n" - "vdup.s8 d10, d1[7] \n" - "vdup.s8 d11, r6 \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d15 \n" - - "vld1.32 {d12-d15}, [%[output0]] \n" - "vadd.s32 q6, q6, q12 \n" - "vadd.s32 q7, q7, q13 \n" - "vst1.32 {d12-d15}, [%[output0]]! \n" - - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q14, q14, d12 \n" - "vaddw.s16 q15, q15, d13 \n" - "vaddw.s16 q14, q14, d14 \n" - "vaddw.s16 q15, q15, d15 \n" - - "vld1.32 {d12-d15}, [%[output1]] \n" - "vadd.s32 q6, q6, q14 \n" - "vadd.s32 q7, q7, q15 \n" - "vst1.32 {d12-d15}, [%[output1]]! \n" - - "vld1.8 {d2-d3}, [%[r3]] \n" // r3 - "add %[r3], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q8, q8, d12 \n" - "vaddw.s16 q9, q9, d15 \n" - "vaddw.s16 q8, q8, d14 \n" - "vaddw.s16 q9, q9, d13 \n" - - "vld1.32 {d12-d15}, [%[output0n]] \n" - "vadd.s32 q6, q6, q8 \n" - "vadd.s32 q7, q7, q9 \n" - "vst1.32 {d12-d15}, [%[output0n]]! \n" - - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q10, q10, d12 \n" - "vaddw.s16 q11, q11, d15 \n" - "vaddw.s16 q10, q10, d14 \n" - "vaddw.s16 q11, q11, d13 \n" - - "vld1.32 {d12-d15}, [%[output1n]] \n" - "vadd.s32 q6, q6, q10 \n" - "vadd.s32 q7, q7, q11 \n" - "vst1.32 {d12-d15}, [%[output1n]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [ow] "+r"(ow), [output0] "+r"(output0), [output1] "+r"(output1), - [output0n] "+r"(output0n), [output1n] "+r"(output1n) - : [kernel0] "r"(kernel0), [kernel1] "r"(kernel1) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "r5", - "r6"); - } - if (remain > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - "vld1.8 {d1}, [%[kernel1]] \n" - "ldr r6, [%[kernel1], #8] \n" - - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "vld1.8 d7, [%[r3]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "add %[r3], #1 \n" - "vdup.s8 d2, r5 \n" - "vdup.s8 d3, r6 \n" - "vext.8 d8, d0, d2, #3 \n" - "vext.8 d9, d0, d2, #6 \n" - "vext.8 d10, d1, d3, #3 \n" - "vext.8 d11, d1, d3, #6 \n" - - "vmull.s8 q6, d4, d0 \n" - "vmull.s8 q7, d5, d8 \n" - "vmlal.s8 q6, d6, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - "vmull.s8 q6, d4, d1 \n" - "vmull.s8 q7, d5, d10 \n" - "vmlal.s8 q6, d6, d11 \n" - "vaddl.s16 q13, d12, d14 \n" - "vdup.s32 d2, d26[1] \n" - "vadd.s32 d26, d26, d2 \n" - "vadd.s32 d26, d26, d27 \n" - - "ldr r7, [%[output0]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0]]! \n" - "ldr r7, [%[output1]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d26 \n" - "vst1.32 d14[0], [%[output1]]! \n" - - "vmull.s8 q6, d5, d0 \n" - "vmull.s8 q7, d6, d8 \n" - "vmlal.s8 q6, d7, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - "vmull.s8 q6, d5, d1 \n" - "vmull.s8 q7, d6, d10 \n" - "vmlal.s8 q6, d7, d11 \n" - "vaddl.s16 q13, d12, d14 \n" - "vdup.s32 d2, d26[1] \n" - "vadd.s32 d26, d26, d2 \n" - "vadd.s32 d26, d26, d27 \n" - - "ldr r7, [%[output0n]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0n]]! \n" - "ldr r7, [%[output1n]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d26 \n" - "vst1.32 d14[0], [%[output1n]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [remain] "+r"(remain), [output0] "+r"(output0), - [output1] "+r"(output1), [output0n] "+r"(output0n), - [output1n] "+r"(output1n) - : [kernel0] "r"(kernel0), [kernel1] "r"(kernel1) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r5", "r6", "r7"); - } - output0 += output_w; - output1 += output_w; - output0n += output_w; - output1n += output_w; - } - // remain output height - for (; oh < output_h; ++oh) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - const int8_t* r3 = r2 + input_w; - const int8_t* r4 = r3 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - "vld1.8 {d1}, [%[kernel1]] \n" - "ldr r6, [%[kernel1], #8] \n" - - "0: \n" - "vld1.8 {d2-d3}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[0] \n" - "vdup.s8 d7, d0[1] \n" - "vdup.s8 d8, d0[2] \n" - "vdup.s8 d9, d1[0] \n" - "vdup.s8 d10, d1[1] \n" - "vdup.s8 d11, d1[2] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q12, d12, d14 \n" - "vaddl.s16 q13, d13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddl.s16 q14, d12, d14 \n" - "vaddl.s16 q15, d13, d15 \n" - - "vld1.8 {d2-d3}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[3] \n" - "vdup.s8 d7, d0[4] \n" - "vdup.s8 d8, d0[5] \n" - "vdup.s8 d9, d1[3] \n" - "vdup.s8 d10, d1[4] \n" - "vdup.s8 d11, d1[5] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q14, q14, d12 \n" - "vaddw.s16 q14, q14, d14 \n" - "vaddw.s16 q15, q15, d13 \n" - "vaddw.s16 q15, q15, d15 \n" - - "vld1.8 {d2-d3}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[6] \n" - "vdup.s8 d7, d0[7] \n" - "vdup.s8 d8, r5 \n" - "vdup.s8 d9, d1[6] \n" - "vdup.s8 d10, d1[7] \n" - "vdup.s8 d11, r6 \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - "vmull.s8 q6, d2, d9 \n" - "vmull.s8 q7, d4, d10 \n" - "vmlal.s8 q6, d5, d11 \n" - "vaddw.s16 q14, q14, d12 \n" - "vaddw.s16 q14, q14, d14 \n" - "vaddw.s16 q15, q15, d13 \n" - "vaddw.s16 q15, q15, d15 \n" - - "vld1.32 {d12-d15}, [%[output0]] \n" - "vadd.s32 q6, q6, q12 \n" - "vadd.s32 q7, q7, q13 \n" - "vst1.32 {d12-d15}, [%[output0]]! \n" - "vld1.32 {d12-d15}, [%[output1]] \n" - "vadd.s32 q6, q6, q14 \n" - "vadd.s32 q7, q7, q15 \n" - "vst1.32 {d12-d15}, [%[output1]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [ow] "+r"(ow), - [output0] "+r"(output0), [output1] "+r"(output1) - : [kernel0] "r"(kernel0), [kernel1] "r"(kernel1) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "r5", - "r6"); - } - - if (remain > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - "vld1.8 {d1}, [%[kernel1]] \n" - "ldr r6, [%[kernel1], #8] \n" - - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "vdup.s8 d2, r5 \n" - "vdup.s8 d3, r6 \n" - "vext.8 d8, d0, d2, #3 \n" - "vext.8 d9, d0, d2, #6 \n" - "vext.8 d10, d1, d3, #3 \n" - "vext.8 d11, d1, d3, #6 \n" - - "vmull.s8 q6, d4, d0 \n" - "vmull.s8 q7, d5, d8 \n" - "vmlal.s8 q6, d6, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - "vmull.s8 q6, d4, d1 \n" - "vmull.s8 q7, d5, d10 \n" - "vmlal.s8 q6, d6, d11 \n" - "vaddl.s16 q13, d12, d14 \n" - "vdup.s32 d2, d26[1] \n" - "vadd.s32 d26, d26, d2 \n" - "vadd.s32 d26, d26, d27 \n" - - "ldr r7, [%[output0]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0]]! \n" - "ldr r7, [%[output1]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d26 \n" - "vst1.32 d14[0], [%[output1]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), - [remain] "+r"(remain), [output0] "+r"(output0), - [output1] "+r"(output1) - : [kernel0] "r"(kernel0), [kernel1] "r"(kernel1) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r5", "r6", "r7"); - } - } - } - } - - for (; oc < output_c; ++oc) { - for (int ic = 0; ic < input_c; ++ic) { - const int8_t* kernel0 = w_data + (oc * input_c + ic) * 9; - int32_t* output0 = out_data + oc * out_image_size; - int32_t* output0n = output0 + output_w; - - int oh = 0; - for (; oh < output_h - 1; oh += 2) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - const int8_t* r3 = r2 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - - "0: \n" - "vld1.8 {d2-d3}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[0] \n" - "vdup.s8 d7, d0[1] \n" - "vdup.s8 d8, d0[2] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q12, d12, d14 \n" - "vaddl.s16 q13, d13, d15 \n" - - "vld1.8 {d2-d3}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q8, d12, d14 \n" - "vaddl.s16 q9, d13, d15 \n" - - "vdup.s8 d6, d0[3] \n" - "vdup.s8 d7, d0[4] \n" - "vdup.s8 d8, d0[5] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - - "vld1.8 {d2-d3}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q8, q8, d12 \n" - "vaddw.s16 q8, q8, d14 \n" - "vaddw.s16 q9, q9, d13 \n" - "vaddw.s16 q9, q9, d15 \n" - - "vdup.s8 d6, d0[6] \n" - "vdup.s8 d7, d0[7] \n" - "vdup.s8 d8, r5 \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - - "vld1.32 {d12-d15}, [%[output0]] \n" - "vadd.s32 q6, q6, q12 \n" - "vadd.s32 q7, q7, q13 \n" - "vst1.32 {d12-d15}, [%[output0]]! \n" - - "vld1.8 {d2-d3}, [%[r3]] \n" // r3 - "add %[r3], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - - "vmull.s8 q6, d2, d6 \n" // next row - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q8, q8, d12 \n" - "vaddw.s16 q8, q8, d14 \n" - "vaddw.s16 q9, q9, d13 \n" - "vaddw.s16 q9, q9, d15 \n" - - "vld1.32 {d12-d15}, [%[output0n]] \n" - "vadd.s32 q6, q6, q8 \n" - "vadd.s32 q7, q7, q9 \n" - "vst1.32 {d12-d15}, [%[output0n]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [ow] "+r"(ow), [output0] "+r"(output0), - [output0n] "+r"(output0n) - : [kernel0] "r"(kernel0) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "r5"); - } - if (remain > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "vld1.8 d7, [%[r3]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "add %[r3], #1 \n" - "vdup.s8 d2, r5 \n" - "vext.8 d8, d0, d2, #3 \n" - "vext.8 d9, d0, d2, #6 \n" - - "vmull.s8 q6, d4, d0 \n" - "vmull.s8 q7, d5, d8 \n" - "vmlal.s8 q6, d6, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - - "ldr r7, [%[output0]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0]]! \n" - - "vmull.s8 q6, d5, d0 \n" - "vmull.s8 q7, d6, d8 \n" - "vmlal.s8 q6, d7, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - - "ldr r7, [%[output0n]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0n]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [remain] "+r"(remain), [output0] "+r"(output0), - [output0n] "+r"(output0n) - : [kernel0] "r"(kernel0) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r5", "r7"); - } - output0 += output_w; - output0n += output_w; - } - // remain output height - for (; oh < output_h; ++oh) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - - "0: \n" - "vld1.8 {d2-d3}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[0] \n" - "vdup.s8 d7, d0[1] \n" - "vdup.s8 d8, d0[2] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddl.s16 q12, d12, d14 \n" - "vaddl.s16 q13, d13, d15 \n" - - "vld1.8 {d2-d3}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[3] \n" - "vdup.s8 d7, d0[4] \n" - "vdup.s8 d8, d0[5] \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - - "vld1.8 {d2-d3}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d4, d2, d3, #1 \n" - "vext.8 d5, d2, d3, #2 \n" - "vdup.s8 d6, d0[6] \n" - "vdup.s8 d7, d0[7] \n" - "vdup.s8 d8, r5 \n" - "vmull.s8 q6, d2, d6 \n" - "vmull.s8 q7, d4, d7 \n" - "vmlal.s8 q6, d5, d8 \n" - "vaddw.s16 q12, q12, d12 \n" - "vaddw.s16 q12, q12, d14 \n" - "vaddw.s16 q13, q13, d13 \n" - "vaddw.s16 q13, q13, d15 \n" - - "vld1.32 {d12-d15}, [%[output0]] \n" - "vadd.s32 q6, q6, q12 \n" - "vadd.s32 q7, q7, q13 \n" - "vst1.32 {d12-d15}, [%[output0]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [ow] "+r"(ow), - [output0] "+r"(output0) - : [kernel0] "r"(kernel0) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "r5"); - } - - if (remain > 0) { - asm volatile( - "vld1.8 {d0}, [%[kernel0]] \n" - "ldr r5, [%[kernel0], #8] \n" - - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "vdup.s8 d2, r5 \n" - "vext.8 d8, d0, d2, #3 \n" - "vext.8 d9, d0, d2, #6 \n" - - "vmull.s8 q6, d4, d0 \n" - "vmull.s8 q7, d5, d8 \n" - "vmlal.s8 q6, d6, d9 \n" - "vaddl.s16 q12, d12, d14 \n" - "vdup.s32 d2, d24[1] \n" - "vadd.s32 d24, d24, d2 \n" - "vadd.s32 d24, d24, d25 \n" - - "ldr r7, [%[output0]] \n" - "vdup.s32 d14, r7 \n" - "vadd.s32 d14, d14, d24 \n" - "vst1.32 d14[0], [%[output0]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), - [remain] "+r"(remain), [output0] "+r"(output0) - : [kernel0] "r"(kernel0) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r5", "r7"); - } - } - } - } -#endif -#else -// TODO(hjchen2) -#endif -} - -} // namespace operators -} // namespace paddle_mobile - -#endif diff --git a/src/operators/math/conv5x5_arm_int8.cpp b/src/operators/math/conv5x5_arm_int8.cpp deleted file mode 100644 index c861c22d184d5428f3ab9c8f3a69b9aca5b697bd..0000000000000000000000000000000000000000 --- a/src/operators/math/conv5x5_arm_int8.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -#ifdef CONV_OP - -#include "operators/math/conv_arm_int8.h" - -namespace paddle_mobile { -namespace operators { - -void conv5x5s1_int8(const framework::Tensor& input, - const framework::Tensor& weight, - framework::Tensor* output) { -#if defined(__ARM_NEON__) || defined(__ARM_NEON) - const int8_t* in_data = input.data(); - const int8_t* w_data = weight.data(); - int32_t* out_data = output->mutable_data(); - // make sure that batch size is 1 - int input_c = input.dims()[1]; - int input_h = input.dims()[2]; - int input_w = input.dims()[3]; - int output_c = output->dims()[1]; - int output_h = output->dims()[2]; - int output_w = output->dims()[3]; - int image_size = input_h * input_w; - int out_image_size = output_h * output_w; - memset(out_data, 0, output_c * out_image_size * sizeof(int32_t)); -#if __aarch64__ - // TODO(hjchen2) -#else - #pragma omp parallel for - for (int oc = 0; oc < output_c; ++oc) { - for (int ic = 0; ic < input_c; ++ic) { - const int8_t* kernel = w_data + (oc * input_c + ic) * 25; - int32_t* output0 = out_data + oc * out_image_size; - int32_t* output1 = output0 + output_w; - int oh = 0; - for (; oh < output_h - 1; oh += 2) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - const int8_t* r3 = r2 + input_w; - const int8_t* r4 = r3 + input_w; - const int8_t* r5 = r4 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile("vld1.8 {d0-d3}, [%[kernel]] \n" - : [kernel] "+r"(kernel) - : - : "cc", "memory", "q0", "q1"); - asm volatile( - "0: \n" - "vld1.8 {d4-d5}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d0[0] \n" - "vdup.s8 d11, d0[1] \n" - "vdup.s8 d12, d0[2] \n" - "vdup.s8 d13, d0[3] \n" - "vdup.s8 d14, d0[4] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q14, d16, d18 \n" - "vaddl.s16 q15, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q14, q14, d16 \n" - "vaddw.s16 q15, q15, d17 \n" - - "vld1.8 {d4-d5}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - - "vmull.s8 q8, d4, d10 \n" // next row - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q10, d16, d18 \n" - "vaddl.s16 q11, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q10, q10, d16 \n" - "vaddw.s16 q11, q11, d17 \n" - - "vdup.s8 d10, d0[5] \n" - "vdup.s8 d11, d0[6] \n" - "vdup.s8 d12, d0[7] \n" - "vdup.s8 d13, d1[0] \n" - "vdup.s8 d14, d1[1] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - - "vmull.s8 q8, d4, d10 \n" // next row - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q10, q10, q12 \n" - "vadd.s32 q11, q11, q13 \n" - - "vdup.s8 d10, d1[2] \n" - "vdup.s8 d11, d1[3] \n" - "vdup.s8 d12, d1[4] \n" - "vdup.s8 d13, d1[5] \n" - "vdup.s8 d14, d1[6] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r3]] \n" // r3 - "add %[r3], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - - "vmull.s8 q8, d4, d10 \n" // next row - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q10, q10, q12 \n" - "vadd.s32 q11, q11, q13 \n" - - "vdup.s8 d10, d1[7] \n" - "vdup.s8 d11, d2[0] \n" - "vdup.s8 d12, d2[1] \n" - "vdup.s8 d13, d2[2] \n" - "vdup.s8 d14, d2[3] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r4]] \n" // r4 - "add %[r4], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - - "vmull.s8 q8, d4, d10 \n" // next row - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q10, q10, q12 \n" - "vadd.s32 q11, q11, q13 \n" - - "vdup.s8 d10, d2[4] \n" - "vdup.s8 d11, d2[5] \n" - "vdup.s8 d12, d2[6] \n" - "vdup.s8 d13, d2[7] \n" - "vdup.s8 d14, d3[0] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.32 {d24-d27}, [%[output0]] \n" - "vadd.s32 q12, q12, q14 \n" - "vadd.s32 q13, q13, q15 \n" - "vst1.32 {d24-d27}, [%[output0]]! \n" - - "vld1.8 {d4-d5}, [%[r5]] \n" // row 5 - "add %[r5], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q10, q10, q12 \n" - "vadd.s32 q11, q11, q13 \n" - - "vld1.32 {d24-d27}, [%[output1]] \n" - "vadd.s32 q12, q12, q10 \n" - "vadd.s32 q13, q13, q11 \n" - "vst1.32 {d24-d27}, [%[output1]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [r4] "+r"(r4), [r5] "+r"(r5), [ow] "+r"(ow), - [output0] "+r"(output0), [output1] "+r"(output1) - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"); - } - if (remain > 0) { - asm volatile("vld1.8 {d0-d3}, [%[kernel]] \n" - : [kernel] "+r"(kernel) - : - : "cc", "memory", "q0", "q1"); - asm volatile( - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "vld1.8 d7, [%[r3]] \n" - "vld1.8 d8, [%[r4]] \n" - "vld1.8 d9, [%[r5]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "add %[r3], #1 \n" - "add %[r4], #1 \n" - "add %[r5], #1 \n" - "vext.8 d10, d0, d1, #5 \n" - "vext.8 d11, d1, d2, #2 \n" - "vext.8 d12, d1, d2, #7 \n" - "vext.8 d13, d2, d3, #4 \n" - - "vmull.s8 q7, d4, d0 \n" - "vmull.s8 q8, d5, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q10, d14, d16 \n" - "vaddw.s16 q10, q10, d18 \n" - "vadd.s32 d4, d20, d21 \n" - "vaddl.s16 q10, d15, d17 \n" - "vaddw.s16 q10, q10, d19 \n" - "vdup.s32 d14, d4[0] \n" - "vdup.s32 d15, d4[1] \n" - "vadd.s32 d15, d15, d14 \n" - "vdup.s32 d14, d20[0] \n" - "vadd.s32 d15, d15, d14 \n" - - "ldr r6, [%[output0]] \n" - "vdup.s32 d14, r6 \n" - "vadd.s32 d15, d15, d14 \n" - "vst1.32 d15[0], [%[output0]]! \n" - - "vmull.s8 q7, d5, d0 \n" - "vmull.s8 q8, d6, d10 \n" - "vmull.s8 q9, d7, d11 \n" - "vmlal.s8 q8, d8, d12 \n" - "vmlal.s8 q9, d9, d13 \n" - "vaddl.s16 q10, d14, d16 \n" - "vaddw.s16 q10, q10, d18 \n" - "vadd.s32 d4, d20, d21 \n" - "vaddl.s16 q10, d15, d17 \n" - "vaddw.s16 q10, q10, d19 \n" - "vdup.s32 d14, d4[0] \n" - "vdup.s32 d15, d4[1] \n" - "vadd.s32 d15, d15, d14 \n" - "vdup.s32 d14, d20[0] \n" - "vadd.s32 d15, d15, d14 \n" - - "ldr r6, [%[output1]] \n" - "vdup.s32 d14, r6 \n" - "vadd.s32 d15, d15, d14 \n" - "vst1.32 d15[0], [%[output1]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [r4] "+r"(r4), [r5] "+r"(r5), [remain] "+r"(remain), - [output0] "+r"(output0), [output1] "+r"(output1) - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r6"); - } - output0 += output_w; - output1 += output_w; - } - // remain output height - for (; oh < output_h; ++oh) { - const int8_t* r0 = in_data + ic * image_size + oh * input_w; - const int8_t* r1 = r0 + input_w; - const int8_t* r2 = r1 + input_w; - const int8_t* r3 = r2 + input_w; - const int8_t* r4 = r3 + input_w; - - int ow = output_w >> 3; - int remain = output_w & 0x7; - if (ow > 0) { - asm volatile("vld1.8 {d0-d3}, [%[kernel]] \n" - : [kernel] "+r"(kernel) - : - : "cc", "memory", "q0", "q1"); - asm volatile( - "0: \n" - "vld1.8 {d4-d5}, [%[r0]] \n" // r0 - "add %[r0], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d0[0] \n" - "vdup.s8 d11, d0[1] \n" - "vdup.s8 d12, d0[2] \n" - "vdup.s8 d13, d0[3] \n" - "vdup.s8 d14, d0[4] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q14, d16, d18 \n" - "vaddl.s16 q15, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q14, q14, d16 \n" - "vaddw.s16 q15, q15, d17 \n" - - "vld1.8 {d4-d5}, [%[r1]] \n" // r1 - "add %[r1], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d0[5] \n" - "vdup.s8 d11, d0[6] \n" - "vdup.s8 d12, d0[7] \n" - "vdup.s8 d13, d1[0] \n" - "vdup.s8 d14, d1[1] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r2]] \n" // r2 - "add %[r2], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d1[2] \n" - "vdup.s8 d11, d1[3] \n" - "vdup.s8 d12, d1[4] \n" - "vdup.s8 d13, d1[5] \n" - "vdup.s8 d14, d1[6] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r3]] \n" // r3 - "add %[r3], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d1[7] \n" - "vdup.s8 d11, d2[0] \n" - "vdup.s8 d12, d2[1] \n" - "vdup.s8 d13, d2[2] \n" - "vdup.s8 d14, d2[3] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.8 {d4-d5}, [%[r4]] \n" // r4 - "add %[r4], #8 \n" - "vext.8 d6, d4, d5, #1 \n" - "vext.8 d7, d4, d5, #2 \n" - "vext.8 d8, d4, d5, #3 \n" - "vext.8 d9, d4, d5, #4 \n" - "vdup.s8 d10, d2[4] \n" - "vdup.s8 d11, d2[5] \n" - "vdup.s8 d12, d2[6] \n" - "vdup.s8 d13, d2[7] \n" - "vdup.s8 d14, d3[0] \n" - "vmull.s8 q8, d4, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q12, d16, d18 \n" - "vaddl.s16 q13, d17, d19 \n" - "vmull.s8 q8, d9, d14 \n" - "vaddw.s16 q12, q12, d16 \n" - "vaddw.s16 q13, q13, d17 \n" - "vadd.s32 q14, q14, q12 \n" - "vadd.s32 q15, q15, q13 \n" - - "vld1.32 {d24-d27}, [%[output0]] \n" - "vadd.s32 q12, q12, q14 \n" - "vadd.s32 q13, q13, q15 \n" - "vst1.32 {d24-d27}, [%[output0]]! \n" - - "subs %[ow], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [r4] "+r"(r4), [ow] "+r"(ow), [output0] "+r"(output0) - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"); - } - - if (remain > 0) { - asm volatile("vld1.8 {d0-d3}, [%[kernel]] \n" - : [kernel] "+r"(kernel) - : - : "cc", "memory", "q0", "q1"); - asm volatile( - "0: \n" - "vld1.8 d4, [%[r0]] \n" - "vld1.8 d5, [%[r1]] \n" - "vld1.8 d6, [%[r2]] \n" - "vld1.8 d7, [%[r3]] \n" - "vld1.8 d8, [%[r4]] \n" - "add %[r0], #1 \n" - "add %[r1], #1 \n" - "add %[r2], #1 \n" - "add %[r3], #1 \n" - "add %[r4], #1 \n" - "vext.8 d10, d0, d1, #5 \n" - "vext.8 d11, d1, d2, #2 \n" - "vext.8 d12, d1, d2, #7 \n" - "vext.8 d13, d2, d3, #4 \n" - - "vmull.s8 q7, d4, d0 \n" - "vmull.s8 q8, d5, d10 \n" - "vmull.s8 q9, d6, d11 \n" - "vmlal.s8 q8, d7, d12 \n" - "vmlal.s8 q9, d8, d13 \n" - "vaddl.s16 q10, d14, d16 \n" - "vaddw.s16 q10, q10, d18 \n" - "vadd.s32 d4, d20, d21 \n" - "vaddl.s16 q10, d15, d17 \n" - "vaddw.s16 q10, q10, d19 \n" - "vdup.s32 d14, d4[0] \n" - "vdup.s32 d15, d4[1] \n" - "vadd.s32 d15, d15, d14 \n" - "vdup.s32 d14, d20[0] \n" - "vadd.s32 d15, d15, d14 \n" - - "ldr r6, [%[output0]] \n" - "vdup.s32 d14, r6 \n" - "vadd.s32 d15, d15, d14 \n" - "vst1.32 d15[0], [%[output0]]! \n" - - "subs %[remain], #1 \n" - "bne 0b \n" - : [r0] "+r"(r0), [r1] "+r"(r1), [r2] "+r"(r2), [r3] "+r"(r3), - [r4] "+r"(r4), [remain] "+r"(remain), [output0] "+r"(output0) - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "r6"); - } - } - } - } -#endif -#else -// TODO(hjchen2) -#endif -} - -} // namespace operators -} // namespace paddle_mobile - -#endif diff --git a/src/operators/math/conv_arm_int8.h b/src/operators/math/conv_arm_int8.h deleted file mode 100644 index 98843e6158bb0f9816bf49a1cbced5a2ea731446..0000000000000000000000000000000000000000 --- a/src/operators/math/conv_arm_int8.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -#ifdef CONV_OP - -#pragma once - -#include "framework/tensor.h" - -namespace paddle_mobile { -namespace operators { - -void conv3x3s1_int8(const framework::Tensor& input, - const framework::Tensor& weight, framework::Tensor* output); - -void conv3x3s1_int8_4c(const framework::Tensor& input, - const framework::Tensor& weight, - framework::Tensor* output); - -void conv5x5s1_int8(const framework::Tensor& input, - const framework::Tensor& weight, framework::Tensor* output); - -} // namespace operators -} // namespace paddle_mobile - -#endif