| 1604 | } |
| 1605 | |
| 1606 | void ShapeInferenceTest::TestMergeHandles(bool input_not_output) { |
| 1607 | NodeDef def; |
| 1608 | InferenceContext c(kVersion, &def, MakeOpDef(2, 2), {S({}), S({})}, {}, {}, |
| 1609 | {}); |
| 1610 | auto make_shape = [&c](std::initializer_list<int64> dim_sizes) { |
| 1611 | ShapeHandle s; |
| 1612 | TF_CHECK_OK(c.MakeShapeFromPartialTensorShape(S(dim_sizes), &s)); |
| 1613 | return s; |
| 1614 | }; |
| 1615 | auto get_shapes_and_types_from_context = [&](int idx) { |
| 1616 | if (input_not_output) { |
| 1617 | return c.input_handle_shapes_and_types(idx); |
| 1618 | } else { |
| 1619 | return c.output_handle_shapes_and_types(idx); |
| 1620 | } |
| 1621 | }; |
| 1622 | auto merge_shapes_and_types_to_context = |
| 1623 | [&](int idx, const std::vector<ShapeAndType>& shapes_and_types) { |
| 1624 | if (input_not_output) { |
| 1625 | return c.MergeInputHandleShapesAndTypes(idx, shapes_and_types); |
| 1626 | } else { |
| 1627 | return c.MergeOutputHandleShapesAndTypes(idx, shapes_and_types); |
| 1628 | } |
| 1629 | }; |
| 1630 | |
| 1631 | EXPECT_TRUE(get_shapes_and_types_from_context(0) == nullptr); |
| 1632 | EXPECT_TRUE(get_shapes_and_types_from_context(1) == nullptr); |
| 1633 | |
| 1634 | // First merge will take the input completely. |
| 1635 | std::vector<ShapeAndType> t{{make_shape({1, 2, 3}), DT_FLOAT}, |
| 1636 | {c.UnknownShape(), DT_INVALID}, |
| 1637 | {make_shape({4, 3, 2, 1}), DT_INT32}}; |
| 1638 | ASSERT_TRUE(merge_shapes_and_types_to_context(0, t)); |
| 1639 | ASSERT_TRUE(get_shapes_and_types_from_context(0) != nullptr); |
| 1640 | std::vector<ShapeAndType> v = *get_shapes_and_types_from_context(0); |
| 1641 | ASSERT_EQ(3, v.size()); |
| 1642 | for (int i = 0; i < v.size(); ++i) { |
| 1643 | EXPECT_TRUE(SameHandle(t[i].shape, v[i].shape)) << i; |
| 1644 | EXPECT_EQ(t[i].dtype, v[i].dtype); |
| 1645 | } |
| 1646 | |
| 1647 | // Merge that fails because wrong number of values passed. |
| 1648 | // Fails, and no changes made. |
| 1649 | ASSERT_FALSE(merge_shapes_and_types_to_context( |
| 1650 | 0, std::vector<ShapeAndType>{{make_shape({1, 2, 3}), DT_FLOAT}})); |
| 1651 | v = *get_shapes_and_types_from_context(0); |
| 1652 | ASSERT_EQ(3, v.size()); |
| 1653 | for (int i = 0; i < v.size(); ++i) { |
| 1654 | EXPECT_TRUE(SameHandle(t[i].shape, v[i].shape)) << i; |
| 1655 | EXPECT_EQ(t[i].dtype, v[i].dtype); |
| 1656 | } |
| 1657 | |
| 1658 | // Only difference is in a mismatched shape. That is ignored, |
| 1659 | // and there are no other changes, so nothing is done. |
| 1660 | // |
| 1661 | // TODO(cwhipkey): in mismatch cases, change Merge*HandleShapesAndTypes to |
| 1662 | // return an error (separate error from 'refined' output)? |
| 1663 | auto t2 = t; |
nothing calls this directly
no test coverage detected