static */
| 1632 | } |
| 1633 | |
| 1634 | /* static */ StatusOr<Shape> ShapeInference::InferConvolveShape( |
| 1635 | const Shape& lhs, const Shape& rhs, int64 feature_group_count, |
| 1636 | int64 batch_group_count, const Window& window, |
| 1637 | const ConvolutionDimensionNumbers& dnums) { |
| 1638 | TF_RETURN_IF_ERROR(ExpectArray(lhs, "lhs of convolution")); |
| 1639 | TF_RETURN_IF_ERROR(ExpectArray(rhs, "rhs of convolution")); |
| 1640 | |
| 1641 | if (feature_group_count <= 0) { |
| 1642 | return InvalidArgument( |
| 1643 | "feature_group_count must be a positive number, got %d", |
| 1644 | feature_group_count); |
| 1645 | } |
| 1646 | |
| 1647 | if (batch_group_count <= 0) { |
| 1648 | return InvalidArgument( |
| 1649 | "batch_group_count must be a positive number, got %d", |
| 1650 | batch_group_count); |
| 1651 | } |
| 1652 | |
| 1653 | if (batch_group_count > 1 && feature_group_count > 1) { |
| 1654 | return InvalidArgument( |
| 1655 | "both batch_group_count %d and feature_group_count %d cannot be " |
| 1656 | "greater than 1", |
| 1657 | batch_group_count, feature_group_count); |
| 1658 | } |
| 1659 | |
| 1660 | if (!ShapeUtil::SameElementTypeIgnoringFpPrecision(lhs, rhs)) { |
| 1661 | return InvalidArgument( |
| 1662 | "Convolution with different element types: %s and %s.", |
| 1663 | ShapeUtil::HumanString(lhs), ShapeUtil::HumanString(rhs)); |
| 1664 | } |
| 1665 | if (dnums.input_spatial_dimensions_size() != |
| 1666 | dnums.kernel_spatial_dimensions_size()) { |
| 1667 | return InvalidArgument( |
| 1668 | "Both arguments to convolution must have same number of dimensions.\n" |
| 1669 | "Numbers: %s", |
| 1670 | dnums.DebugString()); |
| 1671 | } |
| 1672 | |
| 1673 | if (dnums.input_spatial_dimensions_size() != |
| 1674 | dnums.output_spatial_dimensions_size()) { |
| 1675 | return InvalidArgument( |
| 1676 | "Both input and output of convolution must have same number of " |
| 1677 | "dimensions.\nNumbers: %s", |
| 1678 | dnums.DebugString()); |
| 1679 | } |
| 1680 | |
| 1681 | const int num_spatial_dims = dnums.input_spatial_dimensions_size(); |
| 1682 | if (window.dimensions_size() != num_spatial_dims) { |
| 1683 | return InvalidArgument( |
| 1684 | "Window must have same number of dimensions as dimension numbers.\n" |
| 1685 | "Window: %s\nDimension numbers: %s.", |
| 1686 | window.DebugString(), dnums.DebugString()); |
| 1687 | } |
| 1688 | |
| 1689 | const int num_dims = num_spatial_dims + 2; |
| 1690 | if (lhs.rank() != num_dims) { |
| 1691 | return InvalidArgument( |
nothing calls this directly
no test coverage detected