From 4498313de607a2765410b5904001f80f050a68e9 Mon Sep 17 00:00:00 2001 From: zhupengyang <1165938320@qq.com> Date: Fri, 3 Apr 2020 09:51:26 +0800 Subject: [PATCH] [XPU] add yolo_box bridge (#3319) --- lite/kernels/xpu/bridges/CMakeLists.txt | 2 + lite/kernels/xpu/bridges/paddle_use_bridges.h | 1 + lite/kernels/xpu/bridges/yolo_box_op.cc | 85 +++++++++++++++++++ lite/kernels/xpu/subgraph_compute.cc | 8 +- lite/tests/kernels/yolo_box_compute_test.cc | 26 +++--- 5 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 lite/kernels/xpu/bridges/yolo_box_op.cc diff --git a/lite/kernels/xpu/bridges/CMakeLists.txt b/lite/kernels/xpu/bridges/CMakeLists.txt index 29cb83b2b8..93f3cdb445 100644 --- a/lite/kernels/xpu/bridges/CMakeLists.txt +++ b/lite/kernels/xpu/bridges/CMakeLists.txt @@ -25,6 +25,7 @@ lite_cc_library(subgraph_bridge_layer_norm_op_xpu SRCS layer_norm_op.cc DEPS ${x lite_cc_library(subgraph_bridge_dropout_op_xpu SRCS dropout_op.cc DEPS ${xpu_subgraph_bridge_deps}) lite_cc_library(subgraph_bridge_matmul_op_xpu SRCS matmul_op.cc DEPS ${xpu_subgraph_bridge_deps}) lite_cc_library(subgraph_bridge_cast_op_xpu SRCS cast_op.cc DEPS ${xpu_subgraph_bridge_deps}) +lite_cc_library(subgraph_bridge_yolo_box_op_xpu SRCS yolo_box_op.cc DEPS ${xpu_subgraph_bridge_deps}) set(xpu_subgraph_bridges subgraph_bridge_registry @@ -48,6 +49,7 @@ set(xpu_subgraph_bridges subgraph_bridge_dropout_op_xpu subgraph_bridge_matmul_op_xpu subgraph_bridge_cast_op_xpu + subgraph_bridge_yolo_box_op_xpu CACHE INTERNAL "xpu_subgraph_bridges") message(STATUS "+++++ xpu_subgraph_bridges: ${xpu_subgraph_bridges}") diff --git a/lite/kernels/xpu/bridges/paddle_use_bridges.h b/lite/kernels/xpu/bridges/paddle_use_bridges.h index 0c7886c5b2..cf896426f7 100644 --- a/lite/kernels/xpu/bridges/paddle_use_bridges.h +++ b/lite/kernels/xpu/bridges/paddle_use_bridges.h @@ -37,3 +37,4 @@ USE_SUBGRAPH_BRIDGE(gelu, kXPU); USE_SUBGRAPH_BRIDGE(dropout, kXPU); USE_SUBGRAPH_BRIDGE(matmul, kXPU); USE_SUBGRAPH_BRIDGE(cast, kXPU); +USE_SUBGRAPH_BRIDGE(yolo_box, kXPU); diff --git a/lite/kernels/xpu/bridges/yolo_box_op.cc b/lite/kernels/xpu/bridges/yolo_box_op.cc new file mode 100644 index 0000000000..f1b7c01470 --- /dev/null +++ b/lite/kernels/xpu/bridges/yolo_box_op.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2020 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 "lite/kernels/npu/bridges/registry.h" +#include "lite/kernels/xpu/bridges/graph.h" +#include "lite/kernels/xpu/bridges/utility.h" + +namespace paddle { +namespace lite { +namespace subgraph { +namespace xpu { + +int YoloBoxConverter(void* ctx, OpLite* op, KernelBase* kernel) { + CHECK(ctx != nullptr); + CHECK(op != nullptr); + auto graph = static_cast(ctx); + auto op_info = op->op_info(); + auto op_type = op_info->Type(); + auto scope = op->scope(); + VLOG(3) << "[XPU] Converting " + op_type + "..."; + + // Get input and output vars and op attributes + auto x_name = op_info->Input("X").front(); + auto x = scope->FindTensor(x_name); + + auto img_size_name = op_info->Input("ImgSize").front(); + auto img_size = scope->FindTensor(img_size_name); + + auto boxes_name = op_info->Output("Boxes").front(); + auto scores_name = op_info->Output("Scores").front(); + + auto anchors = op_info->GetAttr>("anchors"); + auto class_num = op_info->GetAttr("class_num"); + auto conf_thresh = op_info->GetAttr("conf_thresh"); + auto downsample_ratio = op_info->GetAttr("downsample_ratio"); + + // X node + std::shared_ptr x_node = nullptr; + if (graph->Has(x_name)) { + x_node = graph->Get(x_name); + } else { + x_node = graph->Add(x_name, *x); + } + + // ImgSize node + std::shared_ptr img_size_node = nullptr; + if (graph->Has(img_size_name)) { + img_size_node = graph->Get(img_size_name); + } else { + img_size_node = graph->Add(img_size_name, *img_size); + } + + // Softmax node + auto yolo_box_data = + graph->builder_.CreateYoloBox(*x_node->data(), + *img_size_node->data(), + CvtShape(anchors), + class_num, + conf_thresh, + downsample_ratio); + graph->Add(boxes_name, graph->builder_.GetField(yolo_box_data, 0)); + graph->Add(scores_name, graph->builder_.GetField(yolo_box_data, 1)); + + return SUCCESS; +} + +} // namespace xpu +} // namespace subgraph +} // namespace lite +} // namespace paddle + +REGISTER_SUBGRAPH_BRIDGE(yolo_box, + kXPU, + paddle::lite::subgraph::xpu::YoloBoxConverter); diff --git a/lite/kernels/xpu/subgraph_compute.cc b/lite/kernels/xpu/subgraph_compute.cc index 1b6d374f73..9c2191331c 100644 --- a/lite/kernels/xpu/subgraph_compute.cc +++ b/lite/kernels/xpu/subgraph_compute.cc @@ -34,7 +34,7 @@ int SubgraphEngine::BuildDeviceProgram() { subgraph::xpu::Graph graph; const auto& bridges = subgraph::Registry::Instance(); for (auto& inst : origin_program_) { - auto op = inst.op(); + auto op = const_cast(inst.op()); CHECK(op); op->CheckShape(); op->InferShape(); @@ -43,10 +43,8 @@ int SubgraphEngine::BuildDeviceProgram() { return subgraph::FAILED; } auto kernel = inst.kernel(); - status |= - bridges.Select(op_type, TARGET(kXPU))(reinterpret_cast(&graph), - const_cast(op), - const_cast(kernel)); + status |= bridges.Select(op_type, TARGET(kXPU))( + reinterpret_cast(&graph), op, const_cast(kernel)); if (subgraph::CHECK_FAILED(status)) { return subgraph::FAILED; } diff --git a/lite/tests/kernels/yolo_box_compute_test.cc b/lite/tests/kernels/yolo_box_compute_test.cc index 2e98ce96ce..c41c89608f 100644 --- a/lite/tests/kernels/yolo_box_compute_test.cc +++ b/lite/tests/kernels/yolo_box_compute_test.cc @@ -228,14 +228,14 @@ class YoloBoxComputeTester : public arena::TestCase { } }; -void test_yolobox(Place place) { - for (int class_num : {1, 2, 3, 4}) { - for (float conf_thresh : {0.01, 0.2, 0.7}) { +void TestYoloBox(Place place, float abs_error) { + for (int class_num : {1, 4}) { + for (float conf_thresh : {0.01, 0.2}) { for (int downsample_ratio : {16, 32}) { - std::vector anchor({10, 13, 16, 30}); + std::vector anchor{10, 13, 16, 30, 33, 30}; std::unique_ptr tester(new YoloBoxComputeTester( place, "def", anchor, class_num, conf_thresh, downsample_ratio)); - arena::Arena arena(std::move(tester), place, 2e-5); + arena::Arena arena(std::move(tester), place, abs_error); arena.TestPrecision(); } } @@ -243,13 +243,17 @@ void test_yolobox(Place place) { } TEST(YoloBox, precision) { -// #ifdef LITE_WITH_X86 -// Place place(TARGET(kX86)); -// #endif -#ifdef LITE_WITH_ARM - Place place(TARGET(kARM)); - test_yolobox(place); + float abs_error = 2e-5; + Place place; +#if defined(LITE_WITH_ARM) + place = TARGET(kARM); +#elif defined(LITE_WITH_XPU) + place = TARGET(kXPU); +#else + return; #endif + + TestYoloBox(place, abs_error); } } // namespace lite -- GitLab