static */
| 625 | } // namespace |
| 626 | |
| 627 | /* static */ StatusOr<Shape> ShapeInference::InferDotOpShape( |
| 628 | const Shape& lhs, const Shape& rhs, |
| 629 | const DotDimensionNumbers& dimension_numbers) { |
| 630 | TF_RETURN_IF_ERROR(ExpectArray(lhs, "lhs of dot")); |
| 631 | TF_RETURN_IF_ERROR(ExpectArray(rhs, "rhs of dot")); |
| 632 | |
| 633 | auto fail = [lhs, rhs](const string& addendum) -> Status { |
| 634 | string message = |
| 635 | StrFormat("Cannot infer shape for dot operation: %s <dot> %s.", |
| 636 | ShapeUtil::HumanString(lhs), ShapeUtil::HumanString(rhs)); |
| 637 | if (!addendum.empty()) { |
| 638 | message += " " + addendum; |
| 639 | } |
| 640 | return InvalidArgument("%s", message); |
| 641 | }; |
| 642 | |
| 643 | // Check if both element types are the same. |
| 644 | if (!ShapeUtil::SameElementTypeIgnoringFpPrecision(lhs, rhs)) { |
| 645 | return fail("Element types do not match."); |
| 646 | } |
| 647 | |
| 648 | // Validate basic properties of dot dimension numbers. |
| 649 | TF_RETURN_IF_ERROR(ValidateDotDimensionNumbers(lhs, rhs, dimension_numbers)); |
| 650 | |
| 651 | // Check that number of contracting dimensions match. |
| 652 | if (dimension_numbers.lhs_contracting_dimensions_size() != |
| 653 | dimension_numbers.rhs_contracting_dimensions_size()) { |
| 654 | return fail( |
| 655 | "Must specify the same number of contracting dimensions for lhs and " |
| 656 | "rhs."); |
| 657 | } |
| 658 | // Check that contracting dimension sizes match. |
| 659 | for (int64 i = 0; i < dimension_numbers.lhs_contracting_dimensions_size(); |
| 660 | ++i) { |
| 661 | const int64 lhs_contracting_dimension = |
| 662 | dimension_numbers.lhs_contracting_dimensions(i); |
| 663 | const int64 rhs_contracting_dimension = |
| 664 | dimension_numbers.rhs_contracting_dimensions(i); |
| 665 | if (lhs.dimensions(lhs_contracting_dimension) != |
| 666 | rhs.dimensions(rhs_contracting_dimension)) { |
| 667 | return fail("Contracting dimension sizes do not match."); |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | // Check that number of batch dimensions match. |
| 672 | if (dimension_numbers.lhs_batch_dimensions_size() != |
| 673 | dimension_numbers.rhs_batch_dimensions_size()) { |
| 674 | return fail("Must the same number of batch dimensions for lhs and rhs."); |
| 675 | } |
| 676 | |
| 677 | // Check that batch dimension numbers and sizes match. |
| 678 | for (int64 i = 0; i < dimension_numbers.lhs_batch_dimensions_size(); ++i) { |
| 679 | if (lhs.dimensions(dimension_numbers.lhs_batch_dimensions(i)) != |
| 680 | rhs.dimensions(dimension_numbers.rhs_batch_dimensions(i))) { |
| 681 | return fail("Batch dimension sizes must match for lhs/rhs."); |
| 682 | } |
| 683 | } |
| 684 |
nothing calls this directly
no test coverage detected