diff --git a/src/common/types.cpp b/src/common/types.cpp index 8c8de7765161e61dc75036a87a34fc6abd2df43e..b90fb70f2a81b365f049632cc7281a69ec58e18d 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -40,9 +40,11 @@ const char *G_OP_TYPE_POOL2D = "pool2d"; const char *G_OP_TYPE_PRIOR_BOX = "prior_box"; const char *G_OP_TYPE_RELU = "relu"; const char *G_OP_TYPE_RESHAPE = "reshape"; +const char *G_OP_TYPE_RESHAPE2 = "reshape2"; const char *G_OP_TYPE_SIGMOID = "sigmoid"; const char *G_OP_TYPE_SOFTMAX = "softmax"; const char *G_OP_TYPE_TRANSPOSE = "transpose"; +const char *G_OP_TYPE_TRANSPOSE2 = "transpose2"; const char *G_OP_TYPE_SPLIT = "split"; const char *G_OP_TYPE_FEED = "feed"; const char *G_OP_TYPE_FETCH = "fetch"; @@ -90,6 +92,7 @@ std::unordered_map< {G_OP_TYPE_FEED, {{"X"}, {"Out"}}}, {G_OP_TYPE_FETCH, {{"X"}, {"Out"}}}, {G_OP_TYPE_TRANSPOSE, {{"X"}, {"Out"}}}, + {G_OP_TYPE_TRANSPOSE2, {{"X"}, {"Out", "XShape"}}}, {G_OP_TYPE_BOX_CODER, {{"PriorBox", "PriorBoxVar", "TargetBox"}, {"OutputBox"}}}, {G_OP_TYPE_FUSION_CONV_ADD_BN_RELU, {{"Input"}, {"Out"}}}, @@ -99,6 +102,7 @@ std::unordered_map< {G_OP_TYPE_POLYGON_BOX_TRANSFORM, {{"Input"}, {"Output"}}}, {G_OP_TYPE_FC, {{"X", "Y", "Z"}, {"Out"}}}, {G_OP_TYPE_RESHAPE, {{"X"}, {"Out"}}}, + {G_OP_TYPE_RESHAPE2, {{"X"}, {"Out", "XShape"}}}, {G_OP_TYPE_DEPTHWISE_CONV, {{"Input"}, {"Output"}}}, {G_OP_TYPE_FILL_CONSTANT, {{}, {"Out"}}}, {G_OP_TYPE_FUSION_CONV_ADD_RELU, {{"Input"}, {"Out"}}}, diff --git a/src/framework/load_ops.h b/src/framework/load_ops.h index 2b76b0158fe06e8678208f6f98fcdb71f8d91e51..982f1c0f3525afde8475866c0121343fafc9d5a0 100644 --- a/src/framework/load_ops.h +++ b/src/framework/load_ops.h @@ -109,9 +109,15 @@ LOAD_FUSION_MATCHER(fusion_conv_add_bn_relu); #ifdef RESHAPE_OP LOAD_OP2(reshape, CPU, MALI_GPU); #endif +#ifdef RESHAPE2_OP +LOAD_OP2(reshape2, CPU, MALI_GPU); +#endif #ifdef TRANSPOSE_OP LOAD_OP1(transpose, CPU); #endif +#ifdef TRANSPOSE2_OP +LOAD_OP1(transpose2, CPU); +#endif #ifdef PRIORBOX_OP LOAD_OP1(prior_box, CPU); #endif @@ -221,5 +227,9 @@ LOAD_FUSION_MATCHER(fusion_conv_bn); #ifdef ELEMENTWISESUB_OP LOAD_OP1(elementwise_sub, CPU) #endif +#ifdef QUANT_OP LOAD_OP1(quantize, CPU); +#endif +#ifdef DEQUANT_OP LOAD_OP1(dequantize, CPU); +#endif diff --git a/src/operators/kernel/arm/quantize_kernel.cpp b/src/operators/kernel/arm/quantize_kernel.cpp index e7552d2602b31f9a5c10e3d81122babae8fcf1a8..11a1f0a53d4886e1a07d258b76b3827671471dca 100644 --- a/src/operators/kernel/arm/quantize_kernel.cpp +++ b/src/operators/kernel/arm/quantize_kernel.cpp @@ -135,11 +135,15 @@ static void quantize_round_to_even(const Tensor *input, const float scale, #if defined(__ARM_NEON__) || defined(__ARM_NEON) size_t loop = size >> 4; size_t remain = size & 0xF; + + #pragma omp parallel for for (size_t i = 0; i < loop; ++i) { - float32x4_t r0 = vld1q_f32(x); - float32x4_t r1 = vld1q_f32(x + 4); - float32x4_t r2 = vld1q_f32(x + 8); - float32x4_t r3 = vld1q_f32(x + 12); + const float *local_x = x + (i << 4); + int8_t *local_y = y + (i << 4); + float32x4_t r0 = vld1q_f32(local_x); + float32x4_t r1 = vld1q_f32(local_x + 4); + float32x4_t r2 = vld1q_f32(local_x + 8); + float32x4_t r3 = vld1q_f32(local_x + 12); r0 = vmulq_n_f32(r0, scale); r1 = vmulq_n_f32(r1, scale); r2 = vmulq_n_f32(r2, scale); @@ -156,12 +160,12 @@ static void quantize_round_to_even(const Tensor *input, const float scale, int16x8_t q6 = vcombine_s16(d2, d3); int8x8_t d5 = vmovn_s16(q5); int8x8_t d6 = vmovn_s16(q6); - vst1_s8(y, d5); - vst1_s8(y + 8, d6); - x += 16; - y += 16; + vst1_s8(local_y, d5); + vst1_s8(local_y + 8, d6); } size = remain; + x += (loop << 4); + y += (loop << 4); #endif for (size_t i = 0; i < size; ++i) { float value = x[i] * scale; @@ -187,11 +191,15 @@ static void quantize_round_to_zero(const Tensor *input, const float scale, #ifdef defined(__ARM_NEON__) || defined(__ARM_NEON) size_t loop = size >> 4; size_t remain = size & 0xF; + + #pragma omp parallel for for (size_t i = 0; i < loop; ++i) { - float32x4_t r0 = vld1q_f32(x); - float32x4_t r1 = vld1q_f32(x + 4); - float32x4_t r2 = vld1q_f32(x + 8); - float32x4_t r3 = vld1q_f32(x + 12); + const float *local_x = x + (i << 4); + int8_t *local_y = y + (i << 4); + float32x4_t r0 = vld1q_f32(local_x); + float32x4_t r1 = vld1q_f32(local_x + 4); + float32x4_t r2 = vld1q_f32(local_x + 8); + float32x4_t r3 = vld1q_f32(local_x + 12); r0 = vmulq_n_f32(r0, scale); r1 = vmulq_n_f32(r1, scale); r2 = vmulq_n_f32(r2, scale); @@ -208,12 +216,12 @@ static void quantize_round_to_zero(const Tensor *input, const float scale, int16x8_t q6 = vcombine_s16(d2, d3); int8x8_t d5 = vmovn_s16(q5); int8x8_t d6 = vmovn_s16(q6); - vst1_s8(y, d5); - vst1_s8(y + 8, d6); - x += 16; - y += 16; + vst1_s8(local_y, d5); + vst1_s8(local_y + 8, d6); } size = remain; + x += (loop << 4); + y += (loop << 4); #endif for (size_t i = 0; i < size; ++i) { y[i] = trunc(x[i] * scale); @@ -228,11 +236,15 @@ static void quantize_round_to_nearest(const Tensor *input, const float scale, #if defined(__ARM_NEON__) || defined(__ARM_NEON) size_t loop = size >> 4; size_t remain = size & 0xF; + + #pragma omp parallel for for (size_t i = 0; i < loop; ++i) { - float32x4_t r0 = vld1q_f32(x); - float32x4_t r1 = vld1q_f32(x + 4); - float32x4_t r2 = vld1q_f32(x + 8); - float32x4_t r3 = vld1q_f32(x + 12); + const float *local_x = x + (i << 4); + int8_t *local_y = y + (i << 4); + float32x4_t r0 = vld1q_f32(local_x); + float32x4_t r1 = vld1q_f32(local_x + 4); + float32x4_t r2 = vld1q_f32(local_x + 8); + float32x4_t r3 = vld1q_f32(local_x + 12); r0 = vmulq_n_f32(r0, scale); r1 = vmulq_n_f32(r1, scale); r2 = vmulq_n_f32(r2, scale); @@ -249,12 +261,12 @@ static void quantize_round_to_nearest(const Tensor *input, const float scale, int16x8_t q6 = vcombine_s16(d2, d3); int8x8_t d5 = vmovn_s16(q5); int8x8_t d6 = vmovn_s16(q6); - vst1_s8(y, d5); - vst1_s8(y + 8, d6); - x += 16; - y += 16; + vst1_s8(local_y, d5); + vst1_s8(local_y + 8, d6); } size = remain; + x += (loop << 4); + y += (loop << 4); #endif for (size_t i = 0; i < size; ++i) { y[i] = round(x[i] * scale); diff --git a/src/operators/kernel/arm/reshape2_kernel.cpp b/src/operators/kernel/arm/reshape2_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83bbf112abb8b5e290126d6909a0fe77291f8fac --- /dev/null +++ b/src/operators/kernel/arm/reshape2_kernel.cpp @@ -0,0 +1,37 @@ +/* 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 RESHAPE2_OP + +#include "operators/kernel/reshape2_kernel.h" +#include "operators/kernel/central-arm-func/reshape2_arm_func.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool Reshape2Kernel::Init(Reshape2Param *param) { + return true; +} + +template <> +void Reshape2Kernel::Compute( + const Reshape2Param ¶m) const { + Reshape2Compute(param); +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/transpose2_kernel.cpp b/src/operators/kernel/arm/transpose2_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..656d2768840a52f50c42d3797018aa9aec037783 --- /dev/null +++ b/src/operators/kernel/arm/transpose2_kernel.cpp @@ -0,0 +1,36 @@ +/* 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 TRANSPOSE2_OP + +#include "operators/kernel/transpose2_kernel.h" +#include "operators/kernel/central-arm-func/transpose2_arm_func.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool Transpose2Kernel::Init(Transpose2Param *param) { + return true; +} + +template <> +void Transpose2Kernel::Compute( + const Transpose2Param ¶m) const { + Transpose2Compute(param); +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h b/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h index 0c01ef0072444479d2d2e2f7676b842d89e432ec..b6288380a04c71b3d6467f7f6648db046ae9acc9 100644 --- a/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h +++ b/src/operators/kernel/central-arm-func/elementwise_add_arm_func.h @@ -58,6 +58,7 @@ void ElementwiseAddCompute(const ElementwiseAddParam ¶m) { const float *input_data = input_x->data(); float *output_data = Out->mutable_data(); for (int i = 0; i < batch; ++i) { + #pragma omp parallel for for (int j = 0; j < channels; ++j) { size_t offset = (i * channels + j) * elementwise_num; const float *input = input_data + offset; diff --git a/src/operators/kernel/central-arm-func/reshape2_arm_func.h b/src/operators/kernel/central-arm-func/reshape2_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..c22cf120313b039944932fb4e6cc52aa59a68fd4 --- /dev/null +++ b/src/operators/kernel/central-arm-func/reshape2_arm_func.h @@ -0,0 +1,59 @@ +/* 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 RESHAPE2_OP +#pragma once + +#include +#include "operators/kernel/reshape_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +void Reshape2Compute(const Reshape2Param ¶m) { + const auto *input_x = param.InputX(); + const auto &input_x_dims = input_x->dims(); + auto *out = param.Out(); + framework::DDim out_dims = out->dims(); + const auto *input_shape = param.InputShape(); + + if (input_shape) { + auto *shape_data = input_shape->data(); + framework::Tensor cpu_shape_tensor; + auto shape = + std::vector(shape_data, shape_data + input_shape->numel()); + out_dims = ValidateShape(shape, input_x->dims()); + } else { + auto &shape = param.Shape(); + out_dims = ValidateShape(shape, input_x_dims); + } + + bool inplace = param.Inplace(); + out->Resize(out_dims); + if (!inplace) { + out->mutable_data(); + framework::TensorCopy(*input_x, out); + out->Resize(out_dims); + } else { + out->ShareDataWith(*input_x); + out->Resize(out_dims); + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/central-arm-func/transpose2_arm_func.h b/src/operators/kernel/central-arm-func/transpose2_arm_func.h new file mode 100644 index 0000000000000000000000000000000000000000..dea90e863b20f19820d60d9cce67b6849d3c467b --- /dev/null +++ b/src/operators/kernel/central-arm-func/transpose2_arm_func.h @@ -0,0 +1,70 @@ +/* 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 TRANSPOSE2_OP +#pragma once + +#include +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +void Transpose2Compute(const Transpose2Param& param) { + const auto* input_x = param.InputX(); + const auto input_x_dims = input_x->dims(); + auto* out = param.Out(); + const auto axis = param.Axis(); + const auto* input_x_data = input_x->data(); + auto* out_data = out->mutable_data(); + + size_t ndim = axis.size(); + std::vector xdim(ndim); + std::vector xstride(ndim); + std::vector xout(ndim); + for (int i = 0; i < ndim; i++) { + int j = ndim - 1 - i; + xdim[j] = input_x_dims[axis[i]]; + xstride[j] = 1; + for (int k = axis[i] + 1; k < ndim; k++) { + xstride[j] *= input_x_dims[k]; + } + xout[j] = xstride[j] * xdim[j]; + } + + auto numel = input_x->numel(); + size_t pind = 0; + std::vector ind(ndim); + for (int i = 0; i < numel; i++) { + out_data[i] = input_x_data[pind]; + ind[0]++; + pind += xstride[0]; + for (int j = 0; j < ndim - 1; j++) { + if (ind[j] == xdim[j]) { + ind[j + 1]++; + ind[j] = 0; + pind += xstride[j + 1]; + pind -= xout[j]; + } else { + break; + } + } + } +} + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/reshape2_kernel.h b/src/operators/kernel/reshape2_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d15a619d314e3f5d3085a34cff503e286b5ee37 --- /dev/null +++ b/src/operators/kernel/reshape2_kernel.h @@ -0,0 +1,36 @@ +/* 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 RESHAPE2_OP + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +class Reshape2Kernel + : public framework::OpKernelBase> { + public: + void Compute(const Reshape2Param& param) const; + bool Init(Reshape2Param* param); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/transpose2_kernel.h b/src/operators/kernel/transpose2_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..8ae75ea483ddb887d9c53b32228ff72b41c76097 --- /dev/null +++ b/src/operators/kernel/transpose2_kernel.h @@ -0,0 +1,37 @@ +/* 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 TRANSPOSE2_OP + +#pragma once + +#include + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +class Transpose2Kernel + : public framework::OpKernelBase> { + public: + void Compute(const Transpose2Param& param) const; + bool Init(Transpose2Param* param); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 568cf77b8e4e81732cd9a783c1a9ea64d347102b..c60014094b582036ef2038b04edf7be3313e571e 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -243,6 +243,12 @@ class OpParam { return GetVarValue("Y", outputs, scope); } + template + static T *OutputXShapeFrom(const VariableNameMap &outputs, + const Scope &scope) { + return GetVarValue("XShape", outputs, scope); + } + template static T *OutputBoxesFrom(const VariableNameMap &outputs, const Scope &scope) { @@ -1126,6 +1132,37 @@ class TransposeParam : public OpParam { }; #endif +#ifdef TRANSPOSE2_OP +template +class Transpose2Param : public OpParam { + typedef typename DtypeTensorTrait::gtype GType; + typedef typename DtypeTensorTrait::rtype RType; + + public: + Transpose2Param(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + output_xshape_ = OutputXShapeFrom(outputs, scope); + axis_ = GetAttr>("axis", attrs); + } + + const RType *InputX() const { return input_x_; } + + RType *Out() const { return out_; } + + RType *OutputXShape() const { return output_xshape_; } + + const vector &Axis() const { return axis_; } + + private: + RType *input_x_; + RType *out_; + RType *output_xshape_; + vector axis_; +}; +#endif + #ifdef LOOKUP_OP template class LookupParam : public OpParam { @@ -1233,6 +1270,49 @@ class ReshapeParam : public OpParam { }; #endif +#ifdef RESHAPE2_OP +template +class Reshape2Param : public OpParam { + typedef typename DtypeTensorTrait::gtype GType; + typedef typename DtypeTensorTrait::rtype RType; + + public: + Reshape2Param(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + input_shape_ = InputShapeFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + output_xshape_ = OutputXShapeFrom(outputs, scope); + shape_ = GetAttr>("shape", attrs); + if (HasAttr("inplace", attrs)) { + inplace_ = GetAttr("inplace", attrs); + } else { + inplace_ = false; + } + } + + const RType *InputX() const { return input_x_; } + + const RType *InputShape() const { return input_shape_; } + + RType *Out() const { return out_; } + + RType *OutputXShape() const { return output_xshape_; } + + const vector &Shape() const { return shape_; } + + const bool &Inplace() const { return inplace_; } + + private: + RType *input_x_; + RType *input_shape_; + RType *out_; + RType *output_xshape_; + vector shape_; + bool inplace_; +}; +#endif + #ifdef SCALE_OP template class ScaleParam : public OpParam { diff --git a/src/operators/reshape2_op.cpp b/src/operators/reshape2_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1623076570d466fc53f885374060c5e744365ed --- /dev/null +++ b/src/operators/reshape2_op.cpp @@ -0,0 +1,47 @@ +/* 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 RESHAPE2_OP + +#include "operators/reshape2_op.h" +#include +#include "operators/kernel/reshape_kernel.h" +namespace paddle_mobile { +namespace operators { + +template +void Reshape2Op::InferShape() const { + auto &shape = this->param_.Shape(); + auto input_x_dims = this->param_.InputX()->dims(); + auto out_dims = ValidateShape(shape, input_x_dims); + this->param_.Out()->Resize(out_dims); + std::vector xshape_dims(input_x_dims.size() + 1, 0); + for (int i = 0; i < input_x_dims.size(); ++i) { + xshape_dims[i + 1] = input_x_dims[i]; + } + this->param_.OutputXShape()->Resize(framework::make_ddim(xshape_dims)); +} + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(reshape2, ops::Reshape2Op); +#endif +#ifdef PADDLE_MOBILE_MALI_GPU +REGISTER_OPERATOR_MALI_GPU(reshape2, ops::Reshape2Op); +#endif + +#endif diff --git a/src/operators/reshape2_op.h b/src/operators/reshape2_op.h new file mode 100644 index 0000000000000000000000000000000000000000..3a06c2b9b90233b6ad0bacb6176f4cc274ff1cc0 --- /dev/null +++ b/src/operators/reshape2_op.h @@ -0,0 +1,54 @@ +/* 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 RESHAPE2_OP + +#pragma once + +#include + +#include "framework/operator.h" +#include "operators/kernel/reshape2_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +using paddle_mobile::framework::Tensor; + +template +class Reshape2Op : public framework::OperatorWithKernel< + DeviceType, Reshape2Param, + operators::Reshape2Kernel> { + public: + Reshape2Op(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel, + operators::Reshape2Kernel>( + type, inputs, outputs, attrs, scope) {} + + using framework::OperatorWithKernel< + DeviceType, Reshape2Param, + operators::Reshape2Kernel>::OperatorWithKernel; + void InferShape() const override; + + protected: +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/transpose2_op.cpp b/src/operators/transpose2_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64d07991f60b4057e3d2841afa1bfe6483f31a88 --- /dev/null +++ b/src/operators/transpose2_op.cpp @@ -0,0 +1,64 @@ +/* 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 TRANSPOSE2_OP + +#include + +#include "common/enforce.h" +#include "operators/transpose2_op.h" +namespace paddle_mobile { +namespace operators { + +template +void Transpose2Op::InferShape() const { + auto input_x_dims = this->param_.InputX()->dims(); + auto axis = this->param_.Axis(); + + size_t x_dims_size = input_x_dims.size(); + size_t axis_size = axis.size(); + + PADDLE_MOBILE_ENFORCE((x_dims_size == axis_size), + "input_dims must " + "be equal to the axis_size. ") + + std::vector count(axis_size, 0); + for (size_t i = 0; i < axis_size; i++) { + PADDLE_MOBILE_ENFORCE( + axis[i] < static_cast(axis_size) && ++count[axis[i]] == 1, + "Each element of Attribute axis should be a unique value " + "range from 0 to (dims - 1), " + "where the dims is the axis's size"); + } + framework::DDim out_dims(input_x_dims); + for (size_t i = 0; i < axis_size; i++) { + out_dims[i] = input_x_dims[axis[i]]; + } + this->param_.Out()->Resize(out_dims); + std::vector xshape_dims(input_x_dims.size() + 1, 0); + for (int i = 0; i < input_x_dims.size(); ++i) { + xshape_dims[i + 1] = input_x_dims[i]; + } + this->param_.OutputXShape()->Resize(framework::make_ddim(xshape_dims)); +} + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(transpose2, ops::Transpose2Op); +#endif + +#endif // TRANSPOSE_OP diff --git a/src/operators/transpose2_op.h b/src/operators/transpose2_op.h new file mode 100644 index 0000000000000000000000000000000000000000..f1339cc59e0c71a232eddd5dcef47f62994b80da --- /dev/null +++ b/src/operators/transpose2_op.h @@ -0,0 +1,53 @@ +/* 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 TRANSPOSE2_OP + +#pragma once + +#include + +#include "framework/operator.h" +#include "operators/kernel/transpose2_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +using paddle_mobile::framework::Tensor; + +template +class Transpose2Op : public framework::OperatorWithKernel< + DeviceType, Transpose2Param, + operators::Transpose2Kernel> { + public: + Transpose2Op(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel< + DeviceType, Transpose2Param, + operators::Transpose2Kernel>(type, inputs, outputs, + attrs, scope) {} + + using framework::OperatorWithKernel< + DeviceType, Transpose2Param, + operators::Transpose2Kernel>::OperatorWithKernel; + void InferShape() const override; +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a10088f9b417b628418404b8df3d340b851af383..2bd7169533f637add2a752feaceca8df132cb262 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -184,6 +184,10 @@ if (NOT FOUND_MATCH) ADD_EXECUTABLE(test-transpose-op operators/test_transpose_op.cpp test_helper.h test_include.h) target_link_libraries(test-transpose-op paddle-mobile) + # gen test + ADD_EXECUTABLE(test-transpose2-op operators/test_transpose2_op.cpp test_helper.h test_include.h) + target_link_libraries(test-transpose2-op paddle-mobile) + # gen test ADD_EXECUTABLE(test-multiclassnms-op operators/test_multiclass_nms_op.cpp test_helper.h test_include.h) target_link_libraries(test-multiclassnms-op paddle-mobile) @@ -200,6 +204,10 @@ if (NOT FOUND_MATCH) ADD_EXECUTABLE(test-reshape-op operators/test_reshape_op.cpp test_helper.h test_include.h) target_link_libraries(test-reshape-op paddle-mobile) + # gen test + ADD_EXECUTABLE(test-reshape2-op operators/test_reshape2_op.cpp test_helper.h test_include.h) + target_link_libraries(test-reshape2-op paddle-mobile) + # gen test ADD_EXECUTABLE(test-relu-op operators/test_relu_op.cpp test_helper.h test_include.h) target_link_libraries(test-relu-op paddle-mobile) diff --git a/test/net/test_googlenet.cpp b/test/net/test_googlenet.cpp index c88a78974c330ec270fbcb3f5c28e368ef16440e..f7d29942224b51734cf62988ba8f271f1fa05bc3 100644 --- a/test/net/test_googlenet.cpp +++ b/test/net/test_googlenet.cpp @@ -25,8 +25,8 @@ int main() { paddle_mobile::PaddleMobile paddle_mobile; #endif - paddle_mobile.SetThreadNum(1); - bool optimize = false; + paddle_mobile.SetThreadNum(4); + bool optimize = true; auto time1 = time(); if (paddle_mobile.Load(g_googlenet, optimize)) { auto time2 = time(); @@ -35,10 +35,10 @@ int main() { std::vector output; std::vector dims{1, 3, 224, 224}; GetInput(g_test_image_1x3x224x224, &input, dims); - // // 预热十次 - // for (int i = 0; i < 10; ++i) { - // output = paddle_mobile.Predict(input, dims); - // } + // 预热十次 + for (int i = 0; i < 10; ++i) { + output = paddle_mobile.Predict(input, dims); + } auto time3 = time(); for (int i = 0; i < 10; ++i) { output = paddle_mobile.Predict(input, dims); @@ -47,9 +47,6 @@ int main() { std::cout << "predict cost :" << time_diff(time3, time4) / 10 << "ms" << std::endl; - for (int i = 0; i < output.size(); ++i) { - DLOG << "result[" << i << "] = " << output[i]; - } } return 0; } diff --git a/test/operators/test_batchnorm_op.cpp b/test/operators/test_batchnorm_op.cpp index 4ccad8c1512036c2400a09575b3775e75b26acce..5f064d27f3f3f9cca5428467557c9412f76735c7 100644 --- a/test/operators/test_batchnorm_op.cpp +++ b/test/operators/test_batchnorm_op.cpp @@ -12,8 +12,6 @@ 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. */ -#pragma once - #include "../test_helper.h" #include "../test_include.h" #include "operators/batchnorm_op.h" diff --git a/test/operators/test_box_coder_op.cpp b/test/operators/test_box_coder_op.cpp index 92cba3995c866c67c00491ad5cc38fb094594ad3..aeef10be9650623767af4d2de8913ce53b1d2c59 100644 --- a/test/operators/test_box_coder_op.cpp +++ b/test/operators/test_box_coder_op.cpp @@ -12,7 +12,6 @@ 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. */ -#pragma once #include "../test_include.h" #include "operators/box_coder_op.h" diff --git a/test/operators/test_elementwise_sub_op.cpp b/test/operators/test_elementwise_sub_op.cpp index cfac83eff7a012d52d47f96e088bd8519603cadc..e27361b21c3146675ea856d02d70878e73e8912f 100644 --- a/test/operators/test_elementwise_sub_op.cpp +++ b/test/operators/test_elementwise_sub_op.cpp @@ -12,8 +12,6 @@ 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. */ -#pragma once - #include "../test_helper.h" #include "../test_include.h" #include "operators/elementwise_sub_op.h" diff --git a/test/operators/test_fill_constant_op.cpp b/test/operators/test_fill_constant_op.cpp index b099217d1641eb221b3d0d86d780fb6ecfa929bd..99c65ed821c0a90691070b661a6967a11d4694f7 100644 --- a/test/operators/test_fill_constant_op.cpp +++ b/test/operators/test_fill_constant_op.cpp @@ -12,7 +12,6 @@ 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. */ -#pragma once #include "../test_include.h" #include "operators/fill_constant_op.h" diff --git a/test/operators/test_fusion_fc_op.cpp b/test/operators/test_fusion_fc_op.cpp index a23bde45cb74f0f75e655821b15e66b1cef4c081..aaa2d7b578dbda4c6919210eb4a2fb42ba243e53 100644 --- a/test/operators/test_fusion_fc_op.cpp +++ b/test/operators/test_fusion_fc_op.cpp @@ -12,8 +12,6 @@ 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. */ -#pragma once - #include #include "../test_include.h" #include "operators/fusion_fc_op.h" diff --git a/test/operators/test_im2sequence_op.cpp b/test/operators/test_im2sequence_op.cpp index b45e437e12f95cd9f7050247fc03a152246d8122..6c69d1cc9d94ffd958251ee4ed783d6b5531c455 100644 --- a/test/operators/test_im2sequence_op.cpp +++ b/test/operators/test_im2sequence_op.cpp @@ -12,8 +12,6 @@ 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. */ -#pragma once - #include "../test_helper.h" #include "../test_include.h" #include "operators/im2sequence_op.h" diff --git a/test/operators/test_multiclass_nms_op.cpp b/test/operators/test_multiclass_nms_op.cpp index d1b98d4965fd182ab1adc480279f38cea53974be..3447bbdd10b64d2c2f497bdb4d5af15958a9a95b 100644 --- a/test/operators/test_multiclass_nms_op.cpp +++ b/test/operators/test_multiclass_nms_op.cpp @@ -12,7 +12,6 @@ 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. */ -#pragma once #include "../test_include.h" #include "operators/multiclass_nms_op.h" @@ -31,14 +30,12 @@ class TestMultiClassNMSOp { const std::vector> blocks = to_predict_program_->Blocks(); - // DLOG << " **block size " << blocks.size(); for (auto block_desc : blocks) { std::vector> ops = block_desc->Ops(); - // DLOG << " ops " << ops.size(); for (auto op : ops) { if (op->Type() == "multiclass_nms" && op->Input("BBoxes")[0] == "box_coder_0.tmp_0") { - DLOG << " mul attr size: " << op->GetAttrMap().size(); + DLOG << " attr size: " << op->GetAttrMap().size(); DLOG << " inputs size: " << op->GetInputs().size(); DLOG << " outputs size: " << op->GetOutputs().size(); DLOG << " BBoxes is : " << op->Input("BBoxes")[0]; @@ -55,14 +52,6 @@ class TestMultiClassNMSOp { << op->GetAttrMap().at("nms_top_k").Get(); DLOG << " score_threshold : " << op->GetAttrMap().at("score_threshold").Get(); - // DLOG << " variances : " << - // op->GetAttrMap().at("variances").Get>(); - // DLOG << " aspect_ratios : " << - // op->GetAttrMap().at("aspect_ratios").Get>(); - // DLOG << " min_sizes : " << - // op->GetAttrMap().at("min_sizes").Get>(); - // DLOG << " max_sizes : " << - // op->GetAttrMap().at("max_sizes").Get>(); std::shared_ptr> priorbox = std::make_shared>( op->Type(), op->GetInputs(), op->GetOutputs(), @@ -88,16 +77,12 @@ class TestMultiClassNMSOp { auto *output_tensor = output->GetMutable(); output_tensor->mutable_data({1917, 6}); - // DLOG << typeid(output_tensor).name(); - // DLOG << "output_tensor dims: " << output_tensor->dims(); - std::shared_ptr out_tensor = std::make_shared(); out_tensor.reset(output_tensor); predict(t1, t2, 0); return out_tensor; - // return outvars_tensor; } private: diff --git a/test/operators/test_polygon_box_transform_op.cpp b/test/operators/test_polygon_box_transform_op.cpp index a71177ddbd8e4d8b0f204fd6ec9c948882499cbd..5b30ce1ebfd59db972953e16e4506fa2595b8f04 100644 --- a/test/operators/test_polygon_box_transform_op.cpp +++ b/test/operators/test_polygon_box_transform_op.cpp @@ -12,7 +12,6 @@ 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. */ -#pragma once #include "../test_include.h" #include "operators/polygon_box_transform_op.h" diff --git a/test/operators/test_prior_box_op.cpp b/test/operators/test_prior_box_op.cpp index 8c697a9a7982f05b71caa5bb5f4d12e50dc9d418..2c75d01df297030b4633829ac4b29f7592aaf5c4 100644 --- a/test/operators/test_prior_box_op.cpp +++ b/test/operators/test_prior_box_op.cpp @@ -12,7 +12,6 @@ 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. */ -#pragma once #include "../test_include.h" #include "operators/prior_box_op.h" diff --git a/test/operators/test_reshape2_op.cpp b/test/operators/test_reshape2_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42c348a6274592eb23332620131faa0784a71d28 --- /dev/null +++ b/test/operators/test_reshape2_op.cpp @@ -0,0 +1,142 @@ +/* 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. */ + +#include "../test_include.h" +#include "operators/reshape2_op.h" + +namespace paddle_mobile { +namespace framework { + +template +class TestReshape2Op { + public: + explicit TestReshape2Op(const Program p) : program_(p) { + if (use_optimize_) { + to_predict_program_ = program_.optimizeProgram; + } else { + to_predict_program_ = program_.originProgram; + } + const std::vector> blocks = + to_predict_program_->Blocks(); + for (auto block_desc : blocks) { + std::vector> ops = block_desc->Ops(); + for (auto op : ops) { + if (op->Type() == "reshape2") { + DLOG << " attr size: " << op->GetAttrMap().size(); + std::unordered_map attrs = op->GetAttrMap(); + for (std::unordered_map::iterator it = + attrs.begin(); + it != attrs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + DLOG << " inputs size: " << op->GetInputs().size(); + VariableNameMap inputs = op->GetInputs(); + for (VariableNameMap::iterator it = inputs.begin(); + it != inputs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + DLOG << " outputs size: " << op->GetOutputs().size(); + VariableNameMap outputs = op->GetOutputs(); + for (VariableNameMap::iterator it = outputs.begin(); + it != outputs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + input_var_name = op->Input("X")[0]; + output_var_name = op->Output("Out")[0]; + std::shared_ptr> op_ptr = + std::make_shared>( + op->Type(), op->GetInputs(), op->GetOutputs(), + op->GetAttrMap(), program_.scope); + ops_of_block_[*block_desc.get()].push_back(op_ptr); + return; + } + } + } + } + + std::shared_ptr predict(const Tensor &t) { + auto scope = program_.scope; + Variable *input_feed_value = scope->Var(input_var_name); + auto tensor_input = input_feed_value->GetMutable(); + tensor_input->ShareDataWith(t); + + Variable *output = scope->Var(output_var_name); + auto *output_tensor = output->GetMutable(); + + std::shared_ptr out_tensor = std::make_shared(); + out_tensor.reset(output_tensor); + + predict(t, 0); + + return out_tensor; + } + + private: + const framework::Program program_; + std::shared_ptr to_predict_program_; + std::map>>> + ops_of_block_; + bool use_optimize_ = false; + string input_var_name; + string output_var_name; + + void predict(const Tensor &t, int block_id) { + std::shared_ptr to_predict_block = + to_predict_program_->Block(block_id); + for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); ++j) { + auto op = ops_of_block_[*to_predict_block.get()][j]; + op->Run(); + } + } +}; + +template class TestReshape2Op; +} // namespace framework +} // namespace paddle_mobile + +int main() { + DLOG << "----------**********----------"; + DLOG << "begin to run Reshape2 Test"; + paddle_mobile::Loader loader; + auto program = loader.Load(std::string(g_ocr) + "/model", + std::string(g_ocr) + "/params"); + + paddle_mobile::framework::Tensor input; + SetupTensor(&input, {1, 4, 4}, static_cast(0), + static_cast(1)); + auto *input_ptr = input.data(); + for (int i = 0; i < 16; ++i) { + *(input_ptr + i) = i; + } + DLOG << "input : "; + for (int i = 0; i < input.numel(); ++i) { + DLOG << " index " << i << " : " << input_ptr[i]; + } + + paddle_mobile::framework::TestReshape2Op testReshape2Op( + program); + + auto output = testReshape2Op.predict(input); + auto *output_ptr = output->data(); + + DLOG << "output : "; + for (int i = 0; i < output->numel(); ++i) { + DLOG << " index " << i << " : " << output_ptr[i]; + } + return 0; +} diff --git a/test/operators/test_sum_op.cpp b/test/operators/test_sum_op.cpp index e51d1cff5e99c5d9c444db046e78eee6a03f9243..467529d8d3877fcb9ac5527daf5f037aea6d18fc 100644 --- a/test/operators/test_sum_op.cpp +++ b/test/operators/test_sum_op.cpp @@ -12,8 +12,6 @@ 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. */ -#pragma once - #include "../test_helper.h" #include "../test_include.h" #include "operators/sum_op.h" diff --git a/test/operators/test_transpose2_op.cpp b/test/operators/test_transpose2_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b75a957cd5c1cd08dc09895e9e2448761e822274 --- /dev/null +++ b/test/operators/test_transpose2_op.cpp @@ -0,0 +1,143 @@ +/* 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. */ + +#include "../test_include.h" +#include "operators/transpose2_op.h" + +namespace paddle_mobile { +namespace framework { + +template +class TestTranspose2Op { + public: + explicit TestTranspose2Op(const Program p) : program_(p) { + if (use_optimize_) { + to_predict_program_ = program_.optimizeProgram; + } else { + to_predict_program_ = program_.originProgram; + } + const std::vector> blocks = + to_predict_program_->Blocks(); + for (auto block_desc : blocks) { + std::vector> ops = block_desc->Ops(); + for (auto op : ops) { + if (op->Type() == "transpose2") { + DLOG << " attr size: " << op->GetAttrMap().size(); + std::unordered_map attrs = op->GetAttrMap(); + for (std::unordered_map::iterator it = + attrs.begin(); + it != attrs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + DLOG << " inputs size: " << op->GetInputs().size(); + VariableNameMap inputs = op->GetInputs(); + for (VariableNameMap::iterator it = inputs.begin(); + it != inputs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + DLOG << " outputs size: " << op->GetOutputs().size(); + VariableNameMap outputs = op->GetOutputs(); + for (VariableNameMap::iterator it = outputs.begin(); + it != outputs.end(); ++it) { + DLOG << " " << it->first << " " << it->second; + } + + input_var_name = op->Input("X")[0]; + output_var_name = op->Output("Out")[0]; + std::shared_ptr> op_ptr = + std::make_shared>( + op->Type(), op->GetInputs(), op->GetOutputs(), + op->GetAttrMap(), program_.scope); + ops_of_block_[*block_desc.get()].push_back(op_ptr); + return; + } + } + } + } + + std::shared_ptr predict(const Tensor &t) { + auto scope = program_.scope; + Variable *input_feed_value = scope->Var(input_var_name); + auto tensor_input = input_feed_value->GetMutable(); + tensor_input->ShareDataWith(t); + + Variable *output = scope->Var(output_var_name); + auto *output_tensor = output->GetMutable(); + output_tensor->mutable_data({1, 2, 8}); + + std::shared_ptr out_tensor = std::make_shared(); + out_tensor.reset(output_tensor); + + predict(t, 0); + + return out_tensor; + } + + private: + const framework::Program program_; + std::shared_ptr to_predict_program_; + std::map>>> + ops_of_block_; + bool use_optimize_ = false; + string input_var_name; + string output_var_name; + + void predict(const Tensor &t, int block_id) { + std::shared_ptr to_predict_block = + to_predict_program_->Block(block_id); + for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); ++j) { + auto op = ops_of_block_[*to_predict_block.get()][j]; + op->Run(); + } + } +}; + +template class TestTranspose2Op; +} // namespace framework +} // namespace paddle_mobile + +int main() { + DLOG << "----------**********----------"; + DLOG << "begin to run Transpose2 Test"; + paddle_mobile::Loader loader; + auto program = loader.Load(std::string(g_ocr) + "/model", + std::string(g_ocr) + "/params"); + + paddle_mobile::framework::Tensor input; + SetupTensor(&input, {1, 8, 2}, static_cast(0), + static_cast(1)); + auto *input_ptr = input.data(); + for (int i = 0; i < 16; ++i) { + *(input_ptr + i) = i; + } + DLOG << "input : "; + for (int i = 0; i < input.numel(); ++i) { + DLOG << " index " << i << " : " << input_ptr[i]; + } + + paddle_mobile::framework::TestTranspose2Op + testTranspose2Op(program); + + auto output = testTranspose2Op.predict(input); + auto *output_ptr = output->data(); + + DLOG << "output : "; + for (int i = 0; i < output->numel(); ++i) { + DLOG << " index " << i << " : " << output_ptr[i]; + } + return 0; +} diff --git a/tools/op.cmake b/tools/op.cmake index f7a6ed4b134f78ddb23487cd3a861f244e6a86db..2e1e311a2c96bac02257cfdce2d2fbebcd962dfb 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -201,9 +201,11 @@ if(NOT FOUND_MATCH) set(PRIORBOX_OP ON) set(RELU_OP ON) set(RESHAPE_OP ON) + set(RESHAPE2_OP ON) set(SIGMOID_OP ON) set(SOFTMAX_OP ON) set(TRANSPOSE_OP ON) + set(TRANSPOSE2_OP ON) set(FUSION_CONVADDBNRELU_OP ON) set(FUSION_CONVADDADDPRELU_OP ON) set(FUSION_DWCONVBNRELU_OP ON) @@ -246,9 +248,11 @@ endif() # option(PRIORBOX_OP "" ON) # option(RELU_OP "" ON) # option(RESHAPE_OP "" ON) + # option(RESHAPE2_OP "" ON) # option(SIGMOID_OP "" ON) # option(SOFTMAX_OP "" ON) # option(TRANSPOSE_OP "" ON) + # option(TRANSPOSE2_OP "" ON) # endif () if (BATCHNORM_OP) @@ -314,6 +318,9 @@ endif() if (RESHAPE_OP) add_definitions(-DRESHAPE_OP) endif() +if (RESHAPE2_OP) + add_definitions(-DRESHAPE2_OP) +endif() if (SIGMOID_OP) add_definitions(-DSIGMOID_OP) endif() @@ -323,6 +330,9 @@ endif() if (TRANSPOSE_OP) add_definitions(-DTRANSPOSE_OP) endif() +if (TRANSPOSE2_OP) + add_definitions(-DTRANSPOSE2_OP) +endif() if (FUSION_CONVADDBNRELU_OP) add_definitions(-DFUSION_CONVADDBNRELU_OP) endif()