Skip to content

Commit c816121

Browse files
baiyfqingqing01
authored andcommitted
optimized iou_similarity_op (PaddlePaddle#10231)
1 parent 6d93456 commit c816121

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

paddle/fluid/operators/iou_similarity_op.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,24 @@ struct IOUSimilarityFunctor {
4141
IOUSimilarityFunctor(const T* x, const T* y, T* z, int cols)
4242
: x_(x), y_(y), z_(z), cols_(static_cast<size_t>(cols)) {}
4343

44-
inline HOSTDEVICE void operator()(size_t row_id) const {
44+
inline HOSTDEVICE void operator()(size_t tid) const {
45+
size_t row_id = tid / cols_;
46+
size_t col_id = tid % cols_;
47+
4548
T x_min1 = x_[row_id * 4];
4649
T y_min1 = x_[row_id * 4 + 1];
4750
T x_max1 = x_[row_id * 4 + 2];
4851
T y_max1 = x_[row_id * 4 + 3];
49-
for (size_t i = 0; i < cols_; ++i) {
50-
T x_min2 = y_[i * 4];
51-
T y_min2 = y_[i * 4 + 1];
52-
T x_max2 = y_[i * 4 + 2];
53-
T y_max2 = y_[i * 4 + 3];
5452

55-
T sim = IOUSimilarity(x_min1, y_min1, x_max1, y_max1, x_min2, y_min2,
56-
x_max2, y_max2);
53+
T x_min2 = y_[col_id * 4];
54+
T y_min2 = y_[col_id * 4 + 1];
55+
T x_max2 = y_[col_id * 4 + 2];
56+
T y_max2 = y_[col_id * 4 + 3];
57+
58+
T sim = IOUSimilarity(x_min1, y_min1, x_max1, y_max1, x_min2, y_min2,
59+
x_max2, y_max2);
5760

58-
z_[row_id * cols_ + i] = sim;
59-
}
61+
z_[row_id * cols_ + col_id] = sim;
6062
}
6163
const T* x_;
6264
const T* y_;
@@ -81,7 +83,7 @@ class IOUSimilarityKernel : public framework::OpKernel<T> {
8183
out->mutable_data<T>(ctx.GetPlace()), y_n);
8284

8385
platform::ForRange<DeviceContext> for_range(
84-
static_cast<const DeviceContext&>(ctx.device_context()), x_n);
86+
static_cast<const DeviceContext&>(ctx.device_context()), x_n * y_n);
8587
for_range(functor);
8688
}
8789
}; // namespace operators

python/paddle/fluid/tests/unittests/test_iou_similarity_op.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import unittest
1616
import numpy as np
17+
import numpy.random as random
1718
import sys
1819
import math
1920
from op_test import OpTest
@@ -25,14 +26,27 @@ def test_check_output(self):
2526

2627
def setUp(self):
2728
self.op_type = "iou_similarity"
28-
self.boxes1 = np.array(
29-
[[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]]).astype('float32')
30-
self.boxes2 = np.array([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
31-
[0.0, 0.0, 20.0, 20.0]]).astype('float32')
32-
self.output = np.array(
33-
[[2.0 / 16.0, 0, 6.0 / 400.0],
34-
[1.0 / 16.0, 0.0, 5.0 / 400.0]]).astype('float32')
35-
29+
self.boxes1 = random.rand(2, 4).astype('float32')
30+
self.boxes2 = random.rand(3, 4).astype('float32')
31+
self.output = random.rand(2, 3).astype('float32')
32+
for row in range(self.boxes1.shape[0]):
33+
for col in range(self.boxes2.shape[0]):
34+
xmin1, ymin1, xmax1, ymax1 = self.boxes1[row]
35+
xmin2, ymin2, xmax2, ymax2 = self.boxes2[col]
36+
area1 = (ymax1 - ymin1) * (xmax1 - xmin1)
37+
area2 = (ymax2 - ymin2) * (xmax2 - xmin2)
38+
inter_xmax = min(xmax1, xmax2)
39+
inter_ymax = min(ymax1, ymax2)
40+
inter_xmin = max(xmin1, xmin2)
41+
inter_ymin = max(ymin1, ymin2)
42+
inter_height = inter_ymax - inter_ymin
43+
inter_width = inter_xmax - inter_xmin
44+
inter_height = max(inter_height, 0)
45+
inter_width = max(inter_width, 0)
46+
inter_area = inter_width * inter_height
47+
union_area = area1 + area2 - inter_area
48+
sim_score = inter_area / union_area
49+
self.output[row, col] = sim_score
3650
self.inputs = {'X': self.boxes1, 'Y': self.boxes2}
3751

3852
self.outputs = {'Out': self.output}

0 commit comments

Comments
 (0)