rbox_iou.cc 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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
  16. // https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/csrc/box_iou_rotated/
  17. #include "paddle/extension.h"
  18. #include "rbox_iou_utils.h"
  19. template <typename T>
  20. void rbox_iou_cpu_kernel(const int rbox1_num, const int rbox2_num,
  21. const T *rbox1_data_ptr, const T *rbox2_data_ptr,
  22. T *output_data_ptr) {
  23. int i, j;
  24. for (i = 0; i < rbox1_num; i++) {
  25. for (j = 0; j < rbox2_num; j++) {
  26. int offset = i * rbox2_num + j;
  27. output_data_ptr[offset] =
  28. rbox_iou_single<T>(rbox1_data_ptr + i * 5, rbox2_data_ptr + j * 5);
  29. }
  30. }
  31. }
  32. #define CHECK_INPUT_CPU(x) \
  33. PD_CHECK(x.is_cpu(), #x " must be a CPU Tensor.")
  34. std::vector<paddle::Tensor> RboxIouCPUForward(const paddle::Tensor &rbox1,
  35. const paddle::Tensor &rbox2) {
  36. CHECK_INPUT_CPU(rbox1);
  37. CHECK_INPUT_CPU(rbox2);
  38. auto rbox1_num = rbox1.shape()[0];
  39. auto rbox2_num = rbox2.shape()[0];
  40. auto output =
  41. paddle::empty({rbox1_num, rbox2_num}, rbox1.dtype(), paddle::CPUPlace());
  42. PD_DISPATCH_FLOATING_TYPES(rbox1.type(), "rbox_iou_cpu_kernel", ([&] {
  43. rbox_iou_cpu_kernel<data_t>(
  44. rbox1_num, rbox2_num, rbox1.data<data_t>(),
  45. rbox2.data<data_t>(), output.data<data_t>());
  46. }));
  47. return {output};
  48. }
  49. #ifdef PADDLE_WITH_CUDA
  50. std::vector<paddle::Tensor> RboxIouCUDAForward(const paddle::Tensor &rbox1,
  51. const paddle::Tensor &rbox2);
  52. #endif
  53. #define CHECK_INPUT_SAME(x1, x2) \
  54. PD_CHECK(x1.place() == x2.place(), "input must be smae pacle.")
  55. std::vector<paddle::Tensor> RboxIouForward(const paddle::Tensor &rbox1,
  56. const paddle::Tensor &rbox2) {
  57. CHECK_INPUT_SAME(rbox1, rbox2);
  58. if (rbox1.is_cpu()) {
  59. return RboxIouCPUForward(rbox1, rbox2);
  60. #ifdef PADDLE_WITH_CUDA
  61. } else if (rbox1.is_gpu()) {
  62. return RboxIouCUDAForward(rbox1, rbox2);
  63. #endif
  64. }
  65. }
  66. std::vector<std::vector<int64_t>>
  67. RboxIouInferShape(std::vector<int64_t> rbox1_shape,
  68. std::vector<int64_t> rbox2_shape) {
  69. return {{rbox1_shape[0], rbox2_shape[0]}};
  70. }
  71. std::vector<paddle::DataType> RboxIouInferDtype(paddle::DataType t1,
  72. paddle::DataType t2) {
  73. return {t1};
  74. }
  75. PD_BUILD_OP(rbox_iou)
  76. .Inputs({"RBox1", "RBox2"})
  77. .Outputs({"Output"})
  78. .SetKernelFn(PD_KERNEL(RboxIouForward))
  79. .SetInferShapeFn(PD_INFER_SHAPE(RboxIouInferShape))
  80. .SetInferDtypeFn(PD_INFER_DTYPE(RboxIouInferDtype));