rbox_iou_op.cc 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // The code is based on https://github.com/csuhan/s2anet/blob/master/mmdet/ops/box_iou_rotated
  16. #include "rbox_iou_op.h"
  17. #include "paddle/extension.h"
  18. template <typename T>
  19. void rbox_iou_cpu_kernel(
  20. const int rbox1_num,
  21. const int rbox2_num,
  22. const T* rbox1_data_ptr,
  23. const T* rbox2_data_ptr,
  24. T* output_data_ptr) {
  25. int i, j;
  26. for (i = 0; i < rbox1_num; i++) {
  27. for (j = 0; j < rbox2_num; j++) {
  28. int offset = i * rbox2_num + j;
  29. output_data_ptr[offset] = rbox_iou_single<T>(rbox1_data_ptr + i * 5, rbox2_data_ptr + j * 5);
  30. }
  31. }
  32. }
  33. #define CHECK_INPUT_CPU(x) PD_CHECK(x.place() == paddle::PlaceType::kCPU, #x " must be a CPU Tensor.")
  34. std::vector<paddle::Tensor> RboxIouCPUForward(const paddle::Tensor& rbox1, const paddle::Tensor& rbox2) {
  35. CHECK_INPUT_CPU(rbox1);
  36. CHECK_INPUT_CPU(rbox2);
  37. auto rbox1_num = rbox1.shape()[0];
  38. auto rbox2_num = rbox2.shape()[0];
  39. auto output = paddle::Tensor(paddle::PlaceType::kCPU, {rbox1_num, rbox2_num});
  40. PD_DISPATCH_FLOATING_TYPES(
  41. rbox1.type(),
  42. "rbox_iou_cpu_kernel",
  43. ([&] {
  44. rbox_iou_cpu_kernel<data_t>(
  45. rbox1_num,
  46. rbox2_num,
  47. rbox1.data<data_t>(),
  48. rbox2.data<data_t>(),
  49. output.mutable_data<data_t>());
  50. }));
  51. return {output};
  52. }
  53. #ifdef PADDLE_WITH_CUDA
  54. std::vector<paddle::Tensor> RboxIouCUDAForward(const paddle::Tensor& rbox1, const paddle::Tensor& rbox2);
  55. #endif
  56. #define CHECK_INPUT_SAME(x1, x2) PD_CHECK(x1.place() == x2.place(), "input must be smae pacle.")
  57. std::vector<paddle::Tensor> RboxIouForward(const paddle::Tensor& rbox1, const paddle::Tensor& rbox2) {
  58. CHECK_INPUT_SAME(rbox1, rbox2);
  59. if (rbox1.place() == paddle::PlaceType::kCPU) {
  60. return RboxIouCPUForward(rbox1, rbox2);
  61. #ifdef PADDLE_WITH_CUDA
  62. } else if (rbox1.place() == paddle::PlaceType::kGPU) {
  63. return RboxIouCUDAForward(rbox1, rbox2);
  64. #endif
  65. }
  66. }
  67. std::vector<std::vector<int64_t>> InferShape(std::vector<int64_t> rbox1_shape, std::vector<int64_t> rbox2_shape) {
  68. return {{rbox1_shape[0], rbox2_shape[0]}};
  69. }
  70. std::vector<paddle::DataType> InferDtype(paddle::DataType t1, paddle::DataType t2) {
  71. return {t1};
  72. }
  73. PD_BUILD_OP(rbox_iou)
  74. .Inputs({"RBOX1", "RBOX2"})
  75. .Outputs({"Output"})
  76. .SetKernelFn(PD_KERNEL(RboxIouForward))
  77. .SetInferShapeFn(PD_INFER_SHAPE(InferShape))
  78. .SetInferDtypeFn(PD_INFER_DTYPE(InferDtype));