• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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