1 /* Copyright 2015 The TensorFlow 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
16 #include <memory>
17 #include <string>
18 #include <vector>
19
20 #include "absl/strings/match.h"
21 #include "tensorflow/core/common_runtime/device.h"
22 #include "tensorflow/core/common_runtime/device_factory.h"
23 #include "tensorflow/core/framework/fake_input.h"
24 #include "tensorflow/core/framework/node_def_builder.h"
25 #include "tensorflow/core/framework/tensor.h"
26 #include "tensorflow/core/framework/tensor_shape.h"
27 #include "tensorflow/core/framework/tensor_testutil.h"
28 #include "tensorflow/core/framework/types.h"
29 #include "tensorflow/core/framework/types.pb.h"
30 #include "tensorflow/core/kernels/ops_testutil.h"
31 #include "tensorflow/core/lib/core/status_test_util.h"
32 #include "tensorflow/core/platform/status.h"
33 #include "tensorflow/core/platform/str_util.h"
34 #include "tensorflow/core/platform/test.h"
35
36 namespace tensorflow {
37
38 #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
39 // These tests are copied from non_max_suppression_op_test.cc file and modified
40 // to use GPU ops. See other file for test details.
41
42 class NonMaxSuppressionV2GPUOpTest : public OpsTestBase {
43 protected:
MakeOp()44 void MakeOp() {
45 SetDevice(DEVICE_GPU,
46 std::unique_ptr<tensorflow::Device>(DeviceFactory::NewDevice(
47 "GPU", {}, "/job:a/replica:0/task:0")));
48
49 TF_EXPECT_OK(
50 NodeDefBuilder("non_max_suppression_op_gpu", "NonMaxSuppressionV2")
51 .Input(FakeInput(DT_FLOAT))
52 .Input(FakeInput(DT_FLOAT))
53 .Input(FakeInput(DT_INT32))
54 .Input(FakeInput(DT_FLOAT))
55 .Finalize(node_def()));
56 TF_EXPECT_OK(InitOp());
57 }
58 };
59
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectFromThreeClusters)60 TEST_F(NonMaxSuppressionV2GPUOpTest, TestSelectFromThreeClusters) {
61 MakeOp();
62 AddInputFromArray<float>(
63 TensorShape({6, 4}),
64 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
65 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
66 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
67 AddInputFromArray<int>(TensorShape({}), {3});
68 AddInputFromArray<float>(TensorShape({}), {.5f});
69 TF_ASSERT_OK(RunOpKernel());
70
71 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
72 test::FillValues<int>(&expected, {3, 0, 5});
73 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
74 }
75
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectFromThreeClustersFlippedCoordinates)76 TEST_F(NonMaxSuppressionV2GPUOpTest,
77 TestSelectFromThreeClustersFlippedCoordinates) {
78 MakeOp();
79 AddInputFromArray<float>(TensorShape({6, 4}),
80 {1, 1, 0, 0, // score= 0.9
81 0, 0.1f, 1, 1.1f, // score= 0.75
82 0, .9f, 1, -0.1f, // score= 0.6
83 0, 10, 1, 11, // score= 0.95
84 1, 10.1f, 0, 11.1f, // score= 0.5
85 1, 101, 0, 100}); // score=0.3
86
87 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
88 AddInputFromArray<int>(TensorShape({}), {3});
89 AddInputFromArray<float>(TensorShape({}), {.5f});
90 TF_ASSERT_OK(RunOpKernel());
91
92 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
93 test::FillValues<int>(&expected, {3, 0, 5});
94 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
95 }
96
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectAtMostTwoBoxesFromThreeClusters)97 TEST_F(NonMaxSuppressionV2GPUOpTest,
98 TestSelectAtMostTwoBoxesFromThreeClusters) {
99 MakeOp();
100 AddInputFromArray<float>(
101 TensorShape({6, 4}),
102 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
103 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
104 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
105 AddInputFromArray<int>(TensorShape({}), {2});
106 AddInputFromArray<float>(TensorShape({}), {.5f});
107 TF_ASSERT_OK(RunOpKernel());
108
109 Tensor expected(allocator(), DT_INT32, TensorShape({2}));
110 test::FillValues<int>(&expected, {3, 0});
111 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
112 }
113
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectAtMostThirtyBoxesFromThreeClusters)114 TEST_F(NonMaxSuppressionV2GPUOpTest,
115 TestSelectAtMostThirtyBoxesFromThreeClusters) {
116 MakeOp();
117 AddInputFromArray<float>(
118 TensorShape({6, 4}),
119 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
120 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
121 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
122 AddInputFromArray<int>(TensorShape({}), {30});
123 AddInputFromArray<float>(TensorShape({}), {.5f});
124 TF_ASSERT_OK(RunOpKernel());
125
126 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
127 test::FillValues<int>(&expected, {3, 0, 5});
128 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
129 }
130
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectSingleBox)131 TEST_F(NonMaxSuppressionV2GPUOpTest, TestSelectSingleBox) {
132 MakeOp();
133 AddInputFromArray<float>(TensorShape({1, 4}), {0, 0, 1, 1});
134 AddInputFromArray<float>(TensorShape({1}), {.9f});
135 AddInputFromArray<int>(TensorShape({}), {3});
136 AddInputFromArray<float>(TensorShape({}), {.5f});
137 TF_ASSERT_OK(RunOpKernel());
138
139 Tensor expected(allocator(), DT_INT32, TensorShape({1}));
140 test::FillValues<int>(&expected, {0});
141 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
142 }
143
TEST_F(NonMaxSuppressionV2GPUOpTest,TestSelectFromTenIdenticalBoxes)144 TEST_F(NonMaxSuppressionV2GPUOpTest, TestSelectFromTenIdenticalBoxes) {
145 MakeOp();
146
147 int num_boxes = 10;
148 std::vector<float> corners(num_boxes * 4);
149 std::vector<float> scores(num_boxes);
150 for (int i = 0; i < num_boxes; ++i) {
151 corners[i * 4 + 0] = 0;
152 corners[i * 4 + 1] = 0;
153 corners[i * 4 + 2] = 1;
154 corners[i * 4 + 3] = 1;
155 scores[i] = .9;
156 }
157 AddInputFromArray<float>(TensorShape({num_boxes, 4}), corners);
158 AddInputFromArray<float>(TensorShape({num_boxes}), scores);
159 AddInputFromArray<int>(TensorShape({}), {3});
160 AddInputFromArray<float>(TensorShape({}), {.5f});
161 TF_ASSERT_OK(RunOpKernel());
162
163 Tensor expected(allocator(), DT_INT32, TensorShape({1}));
164 test::FillValues<int>(&expected, {0});
165 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
166 }
167
TEST_F(NonMaxSuppressionV2GPUOpTest,TestInconsistentBoxAndScoreShapes)168 TEST_F(NonMaxSuppressionV2GPUOpTest, TestInconsistentBoxAndScoreShapes) {
169 MakeOp();
170 AddInputFromArray<float>(
171 TensorShape({6, 4}),
172 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
173 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
174 AddInputFromArray<float>(TensorShape({5}), {.9f, .75f, .6f, .95f, .5f});
175 AddInputFromArray<int>(TensorShape({}), {30});
176 AddInputFromArray<float>(TensorShape({}), {.5f});
177 Status s = RunOpKernel();
178
179 ASSERT_FALSE(s.ok());
180 EXPECT_TRUE(
181 str_util::StrContains(s.ToString(), "scores has incompatible shape"))
182 << s;
183 }
184
TEST_F(NonMaxSuppressionV2GPUOpTest,TestInvalidIOUThreshold)185 TEST_F(NonMaxSuppressionV2GPUOpTest, TestInvalidIOUThreshold) {
186 MakeOp();
187 AddInputFromArray<float>(TensorShape({1, 4}), {0, 0, 1, 1});
188 AddInputFromArray<float>(TensorShape({1}), {.9f});
189 AddInputFromArray<int>(TensorShape({}), {3});
190 AddInputFromArray<float>(TensorShape({}), {1.2f});
191 Status s = RunOpKernel();
192
193 ASSERT_FALSE(s.ok());
194 EXPECT_TRUE(
195 str_util::StrContains(s.ToString(), "iou_threshold must be in [0, 1]"))
196 << s;
197 }
198
TEST_F(NonMaxSuppressionV2GPUOpTest,TestEmptyInput)199 TEST_F(NonMaxSuppressionV2GPUOpTest, TestEmptyInput) {
200 MakeOp();
201 AddInputFromArray<float>(TensorShape({0, 4}), {});
202 AddInputFromArray<float>(TensorShape({0}), {});
203 AddInputFromArray<int>(TensorShape({}), {30});
204 AddInputFromArray<float>(TensorShape({}), {.5f});
205 TF_ASSERT_OK(RunOpKernel());
206
207 Tensor expected(allocator(), DT_INT32, TensorShape({0}));
208 test::FillValues<int>(&expected, {});
209 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
210 }
211
212 //
213 // NonMaxSuppressionV3GPUOp Tests
214 // Copied from CPU tests
215
216 class NonMaxSuppressionV3GPUOpTest : public OpsTestBase {
217 protected:
MakeOp()218 void MakeOp() {
219 // TODO(laigd): enable the op once b/140816449 is fixed.
220 // SetDevice(DEVICE_GPU,
221 // std::unique_ptr<tensorflow::Device>(DeviceFactory::NewDevice(
222 // "GPU", {}, "/job:a/replica:0/task:0")));
223
224 TF_EXPECT_OK(NodeDefBuilder("non_max_suppression_op", "NonMaxSuppressionV3")
225 .Input(FakeInput(DT_FLOAT))
226 .Input(FakeInput(DT_FLOAT))
227 .Input(FakeInput(DT_INT32))
228 .Input(FakeInput(DT_FLOAT))
229 .Input(FakeInput(DT_FLOAT))
230 .Finalize(node_def()));
231 TF_EXPECT_OK(InitOp());
232 }
233 };
234
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectFromThreeClusters)235 TEST_F(NonMaxSuppressionV3GPUOpTest, TestSelectFromThreeClusters) {
236 MakeOp();
237 AddInputFromArray<float>(
238 TensorShape({6, 4}),
239 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
240 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
241 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
242 AddInputFromArray<int>(TensorShape({}), {3});
243 AddInputFromArray<float>(TensorShape({}), {.5f});
244 AddInputFromArray<float>(TensorShape({}), {0.0f});
245 TF_ASSERT_OK(RunOpKernel());
246
247 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
248 test::FillValues<int>(&expected, {3, 0, 5});
249 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
250 }
251
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectFromThreeClustersWithScoreThreshold)252 TEST_F(NonMaxSuppressionV3GPUOpTest,
253 TestSelectFromThreeClustersWithScoreThreshold) {
254 MakeOp();
255 AddInputFromArray<float>(
256 TensorShape({6, 4}),
257 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
258 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
259 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
260 AddInputFromArray<int>(TensorShape({}), {3});
261 AddInputFromArray<float>(TensorShape({}), {0.5f});
262 AddInputFromArray<float>(TensorShape({}), {0.4f});
263 TF_ASSERT_OK(RunOpKernel());
264
265 Tensor expected(allocator(), DT_INT32, TensorShape({2}));
266 test::FillValues<int>(&expected, {3, 0});
267 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
268 }
269
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectFromThreeClustersWithScoreThresholdZeroScores)270 TEST_F(NonMaxSuppressionV3GPUOpTest,
271 TestSelectFromThreeClustersWithScoreThresholdZeroScores) {
272 MakeOp();
273 AddInputFromArray<float>(
274 TensorShape({6, 4}),
275 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
276 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
277 AddInputFromArray<float>(TensorShape({6}), {.1, 0, 0, .3, .2, -5.0});
278 // If we ask for more boxes than we actually expect to get back;
279 // should still only get 2 boxes back.
280 AddInputFromArray<int>(TensorShape({}), {6});
281 AddInputFromArray<float>(TensorShape({}), {0.5f});
282 AddInputFromArray<float>(TensorShape({}), {-3.0f});
283 TF_ASSERT_OK(RunOpKernel());
284
285 Tensor expected(allocator(), DT_INT32, TensorShape({2}));
286 test::FillValues<int>(&expected, {3, 0});
287
288 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
289 }
290
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectFromThreeClustersFlippedCoordinates)291 TEST_F(NonMaxSuppressionV3GPUOpTest,
292 TestSelectFromThreeClustersFlippedCoordinates) {
293 MakeOp();
294 AddInputFromArray<float>(TensorShape({6, 4}),
295 {1, 1, 0, 0, 0, 0.1f, 1, 1.1f, 0, .9f, 1, -0.1f,
296 0, 10, 1, 11, 1, 10.1f, 0, 11.1f, 1, 101, 0, 100});
297 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
298 AddInputFromArray<int>(TensorShape({}), {3});
299 AddInputFromArray<float>(TensorShape({}), {.5f});
300 AddInputFromArray<float>(TensorShape({}), {0.0f});
301 TF_ASSERT_OK(RunOpKernel());
302
303 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
304 test::FillValues<int>(&expected, {3, 0, 5});
305 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
306 }
307
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectAtMostTwoBoxesFromThreeClusters)308 TEST_F(NonMaxSuppressionV3GPUOpTest,
309 TestSelectAtMostTwoBoxesFromThreeClusters) {
310 MakeOp();
311 AddInputFromArray<float>(
312 TensorShape({6, 4}),
313 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
314 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
315 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
316 AddInputFromArray<int>(TensorShape({}), {2});
317 AddInputFromArray<float>(TensorShape({}), {.5f});
318 AddInputFromArray<float>(TensorShape({}), {0.0f});
319 TF_ASSERT_OK(RunOpKernel());
320
321 Tensor expected(allocator(), DT_INT32, TensorShape({2}));
322 test::FillValues<int>(&expected, {3, 0});
323 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
324 }
325
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectAtMostThirtyBoxesFromThreeClusters)326 TEST_F(NonMaxSuppressionV3GPUOpTest,
327 TestSelectAtMostThirtyBoxesFromThreeClusters) {
328 MakeOp();
329 AddInputFromArray<float>(
330 TensorShape({6, 4}),
331 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
332 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
333 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
334 AddInputFromArray<int>(TensorShape({}), {30});
335 AddInputFromArray<float>(TensorShape({}), {.5f});
336 AddInputFromArray<float>(TensorShape({}), {0.0f});
337 TF_ASSERT_OK(RunOpKernel());
338
339 Tensor expected(allocator(), DT_INT32, TensorShape({3}));
340 test::FillValues<int>(&expected, {3, 0, 5});
341 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
342 }
343
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectSingleBox)344 TEST_F(NonMaxSuppressionV3GPUOpTest, TestSelectSingleBox) {
345 MakeOp();
346 AddInputFromArray<float>(TensorShape({1, 4}), {0, 0, 1, 1});
347 AddInputFromArray<float>(TensorShape({1}), {.9f});
348 AddInputFromArray<int>(TensorShape({}), {3});
349 AddInputFromArray<float>(TensorShape({}), {.5f});
350 AddInputFromArray<float>(TensorShape({}), {0.0f});
351 TF_ASSERT_OK(RunOpKernel());
352
353 Tensor expected(allocator(), DT_INT32, TensorShape({1}));
354 test::FillValues<int>(&expected, {0});
355 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
356 }
357
TEST_F(NonMaxSuppressionV3GPUOpTest,TestSelectFromTenIdenticalBoxes)358 TEST_F(NonMaxSuppressionV3GPUOpTest, TestSelectFromTenIdenticalBoxes) {
359 MakeOp();
360
361 int num_boxes = 10;
362 std::vector<float> corners(num_boxes * 4);
363 std::vector<float> scores(num_boxes);
364 for (int i = 0; i < num_boxes; ++i) {
365 corners[i * 4 + 0] = 0;
366 corners[i * 4 + 1] = 0;
367 corners[i * 4 + 2] = 1;
368 corners[i * 4 + 3] = 1;
369 scores[i] = .9;
370 }
371 AddInputFromArray<float>(TensorShape({num_boxes, 4}), corners);
372 AddInputFromArray<float>(TensorShape({num_boxes}), scores);
373 AddInputFromArray<int>(TensorShape({}), {3});
374 AddInputFromArray<float>(TensorShape({}), {.5f});
375 AddInputFromArray<float>(TensorShape({}), {0.0f});
376 TF_ASSERT_OK(RunOpKernel());
377
378 Tensor expected(allocator(), DT_INT32, TensorShape({1}));
379 test::FillValues<int>(&expected, {0});
380 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
381 }
382
TEST_F(NonMaxSuppressionV3GPUOpTest,TestInconsistentBoxAndScoreShapes)383 TEST_F(NonMaxSuppressionV3GPUOpTest, TestInconsistentBoxAndScoreShapes) {
384 MakeOp();
385 AddInputFromArray<float>(
386 TensorShape({6, 4}),
387 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
388 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
389 AddInputFromArray<float>(TensorShape({5}), {.9f, .75f, .6f, .95f, .5f});
390 AddInputFromArray<int>(TensorShape({}), {30});
391 AddInputFromArray<float>(TensorShape({}), {.5f});
392 AddInputFromArray<float>(TensorShape({}), {0.0f});
393 Status s = RunOpKernel();
394
395 ASSERT_FALSE(s.ok());
396 EXPECT_TRUE(absl::StrContains(s.ToString(), "scores has incompatible shape"))
397 << s;
398 }
399
TEST_F(NonMaxSuppressionV3GPUOpTest,TestInvalidIOUThreshold)400 TEST_F(NonMaxSuppressionV3GPUOpTest, TestInvalidIOUThreshold) {
401 MakeOp();
402 AddInputFromArray<float>(TensorShape({1, 4}), {0, 0, 1, 1});
403 AddInputFromArray<float>(TensorShape({1}), {.9f});
404 AddInputFromArray<int>(TensorShape({}), {3});
405 AddInputFromArray<float>(TensorShape({}), {1.2f});
406 AddInputFromArray<float>(TensorShape({}), {0.0f});
407 Status s = RunOpKernel();
408
409 ASSERT_FALSE(s.ok());
410 EXPECT_TRUE(
411 absl::StrContains(s.ToString(), "iou_threshold must be in [0, 1]"))
412 << s;
413 }
414
TEST_F(NonMaxSuppressionV3GPUOpTest,TestEmptyInput)415 TEST_F(NonMaxSuppressionV3GPUOpTest, TestEmptyInput) {
416 MakeOp();
417 AddInputFromArray<float>(TensorShape({0, 4}), {});
418 AddInputFromArray<float>(TensorShape({0}), {});
419 AddInputFromArray<int>(TensorShape({}), {30});
420 AddInputFromArray<float>(TensorShape({}), {.5f});
421 AddInputFromArray<float>(TensorShape({}), {0.0f});
422 TF_ASSERT_OK(RunOpKernel());
423
424 Tensor expected(allocator(), DT_INT32, TensorShape({0}));
425 test::FillValues<int>(&expected, {});
426 test::ExpectTensorEqual<int>(expected, *GetOutput(0));
427 }
428
429 //
430 // NonMaxSuppressionV4GPUOp Tests
431 //
432
433 class NonMaxSuppressionV4GPUOpTest : public OpsTestBase {
434 protected:
MakeOp()435 void MakeOp() {
436 // TODO(b/143610288): reenable this once the bug is fixed.
437 // SetDevice(DEVICE_GPU,
438 // std::unique_ptr<tensorflow::Device>(DeviceFactory::NewDevice(
439 // "GPU", {}, "/job:a/replica:0/task:0")));
440
441 TF_EXPECT_OK(NodeDefBuilder("non_max_suppression_op", "NonMaxSuppressionV4")
442 .Input(FakeInput(DT_FLOAT))
443 .Input(FakeInput(DT_FLOAT))
444 .Input(FakeInput(DT_INT32))
445 .Input(FakeInput(DT_FLOAT))
446 .Input(FakeInput(DT_FLOAT))
447 .Attr("pad_to_max_output_size", true)
448 .Finalize(node_def()));
449 TF_EXPECT_OK(InitOp());
450 }
451 };
452
TEST_F(NonMaxSuppressionV4GPUOpTest,TestSelectFromThreeClustersPadFive)453 TEST_F(NonMaxSuppressionV4GPUOpTest, TestSelectFromThreeClustersPadFive) {
454 MakeOp();
455 AddInputFromArray<float>(
456 TensorShape({6, 4}),
457 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
458 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
459 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
460 AddInputFromArray<int>(TensorShape({}), {5});
461 AddInputFromArray<float>(TensorShape({}), {.5f});
462 AddInputFromArray<float>(TensorShape({}), {0.0f});
463 TF_ASSERT_OK(RunOpKernel());
464
465 const auto expected_indices = test::AsTensor<int>({3, 0, 5, 0, 0});
466 test::ExpectTensorEqual<int>(expected_indices, *GetOutput(0));
467 Tensor expected_num_valid = test::AsScalar<int>(3);
468 test::ExpectTensorEqual<int>(expected_num_valid, *GetOutput(1));
469 }
470
TEST_F(NonMaxSuppressionV4GPUOpTest,TestSelectFromThreeClustersPadFiveScoreThr)471 TEST_F(NonMaxSuppressionV4GPUOpTest,
472 TestSelectFromThreeClustersPadFiveScoreThr) {
473 MakeOp();
474 AddInputFromArray<float>(
475 TensorShape({6, 4}),
476 {0, 0, 1, 1, 0, 0.1f, 1, 1.1f, 0, -0.1f, 1, 0.9f,
477 0, 10, 1, 11, 0, 10.1f, 1, 11.1f, 0, 100, 1, 101});
478 AddInputFromArray<float>(TensorShape({6}), {.9f, .75f, .6f, .95f, .5f, .3f});
479 AddInputFromArray<int>(TensorShape({}), {6});
480 AddInputFromArray<float>(TensorShape({}), {.5f});
481 AddInputFromArray<float>(TensorShape({}), {0.4f});
482 TF_ASSERT_OK(RunOpKernel());
483
484 const auto expected_indices = test::AsTensor<int>({3, 0, 0, 0, 0, 0});
485 test::ExpectTensorEqual<int>(expected_indices, *GetOutput(0));
486 Tensor expected_num_valid = test::AsScalar<int>(2);
487 test::ExpectTensorEqual<int>(expected_num_valid, *GetOutput(1));
488 }
489
490 #endif
491
492 } // namespace tensorflow
493