diff --git a/src/common/types.cpp b/src/common/types.cpp index 7edfde6f857daad252fc8ef6174417e4f639d093..cbaf289e27ffcd34eff7b113e06219a595de5257 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -104,6 +104,11 @@ const char *G_OP_TYPE_SEQUENCE_EXPAND = "sequence_expand"; const char *G_OP_TYPE_SEQUENCE_POOL = "sequence_pool"; const char *G_OP_TYPE_SEQUENCE_SOFTMAX = "sequence_softmax"; +const char *G_OP_TYPE_SLICE = "slice"; +const char *G_OP_TYPE_ANCHOR_GENERATOR = "anchor_generator"; +const char *G_OP_TYPE_GENERATE_PROPOSALS = "generate_proposals"; +const char *G_OP_TYPE_PSROI_POOL = "psroi_pool"; + std::unordered_map< std::string, std::pair, std::vector>> op_input_output_key = { @@ -193,5 +198,11 @@ std::unordered_map< {G_OP_TYPE_LOGICAL_XOR, {{"X", "Y"}, {"Out"}}}, {G_OP_TYPE_LOGICAL_NOT, {{"X"}, {"Out"}}}, {G_OP_TYPE_WRITE_TO_ARRAY, {{"X", "I"}, {"Out"}}}, - {G_OP_TYPE_READ_FROM_ARRAY, {{"X", "I"}, {"Out"}}}}; + {G_OP_TYPE_READ_FROM_ARRAY, {{"X", "I"}, {"Out"}}}, + {G_OP_TYPE_SLICE, {{"Input"}, {"Out"}}}, + {G_OP_TYPE_ANCHOR_GENERATOR, {{"Input"}, {"Anchors", "Variances"}}}, + {G_OP_TYPE_GENERATE_PROPOSALS, + {{"Scores", "BboxDeltas", "ImInfo", "Anchors", "Variances"}, + {"RpnRois", "RpnRoiProbs"}}}, + {G_OP_TYPE_PSROI_POOL, {{"X", "ROIs"}, {"Out"}}}}; } // namespace paddle_mobile diff --git a/src/common/types.h b/src/common/types.h index 31d8020d4d3a715683f08f0d27e5463f7865abcc..267015539fa7d3ed7868f841ce22a83ed665e972 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -192,6 +192,11 @@ extern const char *G_OP_TYPE_SEQUENCE_EXPAND; extern const char *G_OP_TYPE_SEQUENCE_POOL; extern const char *G_OP_TYPE_SEQUENCE_SOFTMAX; +extern const char *G_OP_TYPE_SLICE; +extern const char *G_OP_TYPE_ANCHOR_GENERATOR; +extern const char *G_OP_TYPE_GENERATE_PROPOSALS; +extern const char *G_OP_TYPE_PSROI_POOL; + extern std::unordered_map< std::string, std::pair, std::vector>> op_input_output_key; diff --git a/src/framework/load_ops.h b/src/framework/load_ops.h index eadef7d6688291af2b44c686d78ba6b950abbbba..0727c0cb04ec93047e612863f23dd92cb131cbed 100644 --- a/src/framework/load_ops.h +++ b/src/framework/load_ops.h @@ -306,3 +306,12 @@ LOAD_OP1(write_to_array, CPU); #ifdef READ_FROM_ARRAY_OP LOAD_OP1(read_from_array, CPU); #endif +#ifdef ANCHOR_GENERATOR_OP +LOAD_OP1(anchor_generator, CPU); +#endif +#ifdef PROPOSAL_OP +LOAD_OP1(generate_proposals, CPU); +#endif +#ifdef PSROI_POOL_OP +LOAD_OP1(psroi_pool, CPU); +#endif diff --git a/src/operators/detection_ops.cpp b/src/operators/detection_ops.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ce53dca939f5725d03fa0137ee4655515d242ab --- /dev/null +++ b/src/operators/detection_ops.cpp @@ -0,0 +1,81 @@ +/* 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 "operators/detection_ops.h" +#include + +namespace paddle_mobile { +namespace operators { + +#ifdef ANCHOR_GENERATOR_OP +template +void AnchorGeneratorOp::InferShape() const { + const auto &input_dims = this->param_.input_->dims(); + PADDLE_MOBILE_ENFORCE(input_dims.size() == 4, "The layout of input is NCHW."); + const auto &anchor_sizes = this->param_.anchor_sizes_; + const auto &aspect_ratios = this->param_.aspect_ratios_; + + size_t num_anchors = aspect_ratios.size() * anchor_sizes.size(); + std::vector dim_vec(4); + dim_vec[0] = input_dims[2]; + dim_vec[1] = input_dims[3]; + dim_vec[2] = num_anchors; + dim_vec[3] = 4; + + this->param_.output_anchors_->Resize(framework::make_ddim(dim_vec)); + this->param_.output_variances_->Resize(framework::make_ddim(dim_vec)); +} +#endif + +#ifdef PROPOSAL_OP +template +void ProposalOp::InferShape() const { + this->param_.rpn_rois_->Resize(framework::make_ddim({-1, 4})); + this->param_.rpn_probs_->Resize(framework::make_ddim({-1, 1})); +} +#endif + +#ifdef PSROI_POOL_OP +template +void PSRoiPoolOp::InferShape() const { + const auto &rois_dims = this->param_.input_rois_->dims(); + const int pooled_height = this->param_.pooled_height_; + const int pooled_width = this->param_.pooled_width_; + const int output_channels = this->param_.output_channels_; + + auto out_dims = this->param_.input_x_->dims(); + out_dims[0] = rois_dims[0]; + out_dims[1] = + output_channels; // input_dims[1] / (pooled_height * pooled_width); + out_dims[2] = pooled_height; + out_dims[3] = pooled_width; + this->param_.output_->Resize(out_dims); +} +#endif + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +#ifdef ANCHOR_GENERATOR_OP +REGISTER_OPERATOR_CPU(anchor_generator, ops::AnchorGeneratorOp); +#endif +#ifdef PROPOSAL_OP +REGISTER_OPERATOR_CPU(generate_proposals, ops::ProposalOp); +#endif +#ifdef PSROI_POOL_OP +REGISTER_OPERATOR_CPU(psroi_pool, ops::PSRoiPoolOp); +#endif +#endif diff --git a/src/operators/detection_ops.h b/src/operators/detection_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..e69a2d3e7dff43b42d25ca63f67c1ce067e28df9 --- /dev/null +++ b/src/operators/detection_ops.h @@ -0,0 +1,38 @@ +/* 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. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/detection_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef ANCHOR_GENERATOR_OP +DECLARE_OPERATOR(AnchorGenerator, AnchorGeneratorParam, AnchorGeneratorKernel); +#endif + +#ifdef PROPOSAL_OP +DECLARE_OPERATOR(Proposal, ProposalParam, ProposalKernel); +#endif + +#ifdef PSROI_POOL_OP +DECLARE_OPERATOR(PSRoiPool, PSRoiPoolParam, PSRoiPoolKernel); +#endif + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/anchor_generator_kernel.cpp b/src/operators/kernel/arm/anchor_generator_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c493d78bb0955593cfd2528bd54ec115daa66916 --- /dev/null +++ b/src/operators/kernel/arm/anchor_generator_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 ANCHOR_GENERATOR_OP + +#include +#include "operators/kernel/detection_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool AnchorGeneratorKernel::Init(AnchorGeneratorParam *param) { + return true; +} + +template <> +void AnchorGeneratorKernel::Compute( + const AnchorGeneratorParam ¶m) { + // TODO(hjchen2) +} + +} // namespace operators +} // namespace paddle_mobile + +#endif // ANCHOR_GENERATOR_OP diff --git a/src/operators/kernel/arm/proposal_kernel.cpp b/src/operators/kernel/arm/proposal_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9d0c18448c6b19effa7ca4d905eadfe03e6fbaf --- /dev/null +++ b/src/operators/kernel/arm/proposal_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 PROPOSAL_OP + +#include +#include "operators/kernel/detection_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool ProposalKernel::Init(ProposalParam *param) { + return true; +} + +template <> +void ProposalKernel::Compute(const ProposalParam ¶m) { + // TODO(hjchen2) +} + +} // namespace operators +} // namespace paddle_mobile + +#endif // PROPOSAL_OP diff --git a/src/operators/kernel/arm/psroi_pool_kernel.cpp b/src/operators/kernel/arm/psroi_pool_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ed4c77d2d7ab8ed31c8b409d54fd52036e60210 --- /dev/null +++ b/src/operators/kernel/arm/psroi_pool_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 PSROI_POOL_OP + +#include +#include "operators/kernel/detection_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool PSRoiPoolKernel::Init(PSRoiPoolParam *param) { + return true; +} + +template <> +void PSRoiPoolKernel::Compute(const PSRoiPoolParam ¶m) { + // TODO(hjchen2) +} + +} // namespace operators +} // namespace paddle_mobile + +#endif // PSROI_POOL_OP diff --git a/src/operators/kernel/detection_kernel.h b/src/operators/kernel/detection_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..c0047c23901922ae87ba188d605b0ccca8128fc0 --- /dev/null +++ b/src/operators/kernel/detection_kernel.h @@ -0,0 +1,140 @@ +/* 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. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef ANCHOR_GENERATOR_OP +template +class AnchorGeneratorParam : public OpParam { + public: + AnchorGeneratorParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_ = OpParam::GetVarValue("Input", inputs, scope); + output_anchors_ = + OpParam::GetVarValue("Anchors", outputs, scope); + output_variances_ = + OpParam::GetVarValue("Variances", outputs, scope); + + anchor_sizes_ = OpParam::GetAttr>("anchor_sizes", attrs); + aspect_ratios_ = + OpParam::GetAttr>("aspect_ratios", attrs); + variances_ = OpParam::GetAttr>("variances", attrs); + stride_ = OpParam::GetAttr>("stride", attrs); + offset_ = OpParam::GetAttr("offset", attrs); + } + + public: + // input + framework::Tensor *input_; + // outputs + framework::Tensor *output_anchors_; + framework::Tensor *output_variances_; + + std::vector anchor_sizes_; + std::vector aspect_ratios_; + std::vector variances_; + std::vector stride_; + float offset_; +}; + +DECLARE_KERNEL(AnchorGenerator, AnchorGeneratorParam); +#endif + +#ifdef PROPOSAL_OP +template +class ProposalParam : public OpParam { + public: + ProposalParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + scores_ = OpParam::GetVarValue("Scores", inputs, scope); + bbox_deltas_ = + OpParam::GetVarValue("BboxDeltas", inputs, scope); + im_info_ = OpParam::GetVarValue("ImInfo", inputs, scope); + anchors_ = + OpParam::GetVarValue("Anchors", inputs, scope); + variances_ = + OpParam::GetVarValue("Variances", inputs, scope); + + rpn_rois_ = + OpParam::GetVarValue("RpnRois", outputs, scope); + rpn_probs_ = OpParam::GetVarValue("RpnRoiProbs", + outputs, scope); + + pre_nms_topn_ = OpParam::GetAttr("pre_nms_topN", attrs); + post_nms_topn_ = OpParam::GetAttr("post_nms_topN", attrs); + nms_thresh_ = OpParam::GetAttr("nms_thresh", attrs); + min_size_ = OpParam::GetAttr("min_size", attrs); + eta_ = OpParam::GetAttr("eta", attrs); + } + + public: + framework::Tensor *scores_; + framework::Tensor *bbox_deltas_; + framework::Tensor *im_info_; + framework::Tensor *anchors_; + framework::Tensor *variances_; + + framework::LoDTensor *rpn_rois_; + framework::LoDTensor *rpn_probs_; + + int pre_nms_topn_; + int post_nms_topn_; + float nms_thresh_; + float min_size_; + float eta_; +}; + +DECLARE_KERNEL(Proposal, ProposalParam); +#endif + +#ifdef PSROI_POOL_OP +template +class PSRoiPoolParam : public OpParam { + public: + PSRoiPoolParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = OpParam::GetVarValue("X", inputs, scope); + input_rois_ = + OpParam::GetVarValue("ROIs", inputs, scope); + output_ = OpParam::GetVarValue("Out", outputs, scope); + + output_channels_ = OpParam::GetAttr("output_channels", attrs); + pooled_height_ = OpParam::GetAttr("pooled_height", attrs); + pooled_width_ = OpParam::GetAttr("pooled_width", attrs); + spatial_scale_ = OpParam::GetAttr("spatial_scale", attrs); + } + + public: + framework::Tensor *input_x_; + framework::LoDTensor *input_rois_; + framework::Tensor *output_; + int output_channels_; + int pooled_height_; + int pooled_width_; + float spatial_scale_; +}; + +DECLARE_KERNEL(PSRoiPool, PSRoiPoolParam); +#endif + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 959bfd7f743401a453ab0169ca773285e2904d4e..46d4de05f0653f4bc614984a6a322cdf75060c8a 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -1498,33 +1498,20 @@ class SliceParam : public OpParam { public: SliceParam(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); - axis_ = GetAttr("axis", attrs); - slice_points_ = GetAttr>("slice_points", attrs); - inplace_ = GetAttr("inplace", attrs); - } - - const RType *InputX() const { return input_x_; } - - const RType *InputShape() const { return input_shape_; } - - RType *Out() const { return out_; } - - const int &Axis() const { return axis_; } - - const vector &SlicePoints() const { return slice_points_; } + input_ = InputFrom(inputs, scope); + output_ = OutFrom(outputs, scope); - const bool &Inplace() const { return inplace_; } + axes_ = GetAttr>("axes", attrs); + starts_ = GetAttr>("starts", attrs); + ends_ = GetAttr>("ends", attrs); + } - private: - RType *input_x_; - RType *input_shape_; - RType *out_; - int axis_; - vector slice_points_; - bool inplace_; + public: + GType *input_; + GType *output_; + std::vector axes_; + std::vector starts_; + std::vector ends_; }; #endif diff --git a/test/operators/test_conv_op.cpp b/test/operators/test_conv_op.cpp index ecc2455817d73c511190cb19d8ef5e09736fdef6..3a949daefeb89df1c72702f1207a0d0f0e652f93 100644 --- a/test/operators/test_conv_op.cpp +++ b/test/operators/test_conv_op.cpp @@ -228,39 +228,39 @@ int TestAll(const int in_channels, const int in_height, const int in_width, std::cerr << "in_channels=" << in_channels << ", in_height=" << in_height << ", in_width=" << in_width << ", out_channels=" << out_channels << ", groups=" << groups << std::endl; - // kernel = 3, pad = 0, stride = 1 - std::cerr << "float, kernel=3, pad=0, stride=1" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 1, stride = 1 - std::cerr << "float, kernel=3, pad=1, stride=1" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 2, stride = 1 - std::cerr << "float, kernel=3, pad=2, stride=1" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 5, stride = 1 - std::cerr << "float, kernel=3, pad=5, stride=1" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - - // kernel = 3, pad = 0, stride = 2 - std::cerr << "float, kernel=3, pad=0, stride=2" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 1, stride = 2 - std::cerr << "float, kernel=3, pad=1, stride=2" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 2, stride = 2 - std::cerr << "float, kernel=3, pad=2, stride=2" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); - // kernel = 3, pad = 5, stride = 2 - std::cerr << "float, kernel=3, pad=5, stride=2" << std::endl; - paddle_mobile::TestConvOp( - in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 0, stride = 1 + // std::cerr << "float, kernel=3, pad=0, stride=1" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 1, stride = 1 + // std::cerr << "float, kernel=3, pad=1, stride=1" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 2, stride = 1 + // std::cerr << "float, kernel=3, pad=2, stride=1" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 5, stride = 1 + // std::cerr << "float, kernel=3, pad=5, stride=1" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // + // // kernel = 3, pad = 0, stride = 2 + // std::cerr << "float, kernel=3, pad=0, stride=2" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 1, stride = 2 + // std::cerr << "float, kernel=3, pad=1, stride=2" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 2, stride = 2 + // std::cerr << "float, kernel=3, pad=2, stride=2" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); + // // kernel = 3, pad = 5, stride = 2 + // std::cerr << "float, kernel=3, pad=5, stride=2" << std::endl; + // paddle_mobile::TestConvOp( + // in_channels, in_height, in_width, out_channels, groups); #ifndef __aarch64__ // kernel = 3, pad = 0, stride = 1 diff --git a/tools/op.cmake b/tools/op.cmake index 65afb07054e107dfc29d27c7ce547f926b318df0..0f37eb7e98f053f519a1fb0d6a2829b33e82e45a 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -288,6 +288,9 @@ if(NOT FOUND_MATCH) set(WHILE_OP ON) set(WRITE_TO_ARRAY_OP ON) set(READ_FROM_ARRAY_OP ON) + set(ANCHOR_GENERATOR_OP ON) + set(PROPOSAL_OP ON) + set(PSROI_POOL_OP ON) endif() # option(BATCHNORM_OP "" ON) @@ -572,3 +575,13 @@ endif() if (READ_FROM_ARRAY_OP) add_definitions(-DREAD_FROM_ARRAY_OP) endif() + +if (ANCHOR_GENERATOR_OP) + add_definitions(-DANCHOR_GENERATOR_OP) +endif() +if (PROPOSAL_OP) + add_definitions(-DPROPOSAL_OP) +endif() +if (PSROI_POOL_OP) + add_definitions(-DPSROI_POOL_OP) +endif()