| 693 | namespace { |
| 694 | |
| 695 | Status Conv2DShapeImpl(shape_inference::InferenceContext* c, |
| 696 | bool supports_explicit_padding, |
| 697 | string padding_attr_name = "explicit_paddings") { |
| 698 | string data_format_str, filter_format_str; |
| 699 | if (!c->GetAttr("data_format", &data_format_str).ok()) { |
| 700 | data_format_str = "NHWC"; |
| 701 | } |
| 702 | if (!c->GetAttr("filter_format", &filter_format_str).ok()) { |
| 703 | filter_format_str = "HWIO"; |
| 704 | } |
| 705 | |
| 706 | TensorFormat data_format; |
| 707 | if (!FormatFromString(data_format_str, &data_format)) { |
| 708 | return errors::InvalidArgument("Invalid data format string: ", |
| 709 | data_format_str); |
| 710 | } |
| 711 | FilterTensorFormat filter_format; |
| 712 | if (!FilterFormatFromString(filter_format_str, &filter_format)) { |
| 713 | return errors::InvalidArgument("Invalid filter format string: ", |
| 714 | filter_format_str); |
| 715 | } |
| 716 | |
| 717 | constexpr int num_spatial_dims = 2; |
| 718 | const int rank = GetTensorDimsFromSpatialDims(num_spatial_dims, data_format); |
| 719 | ShapeHandle conv_input_shape; |
| 720 | TF_RETURN_IF_ERROR(c->WithRank(c->input(0), rank, &conv_input_shape)); |
| 721 | TF_RETURN_IF_ERROR(CheckFormatConstraintsOnShape( |
| 722 | data_format, conv_input_shape, "conv_input", c)); |
| 723 | |
| 724 | // The filter rank should match the input (4 for NCHW, 5 for NCHW_VECT_C). |
| 725 | ShapeHandle filter_shape; |
| 726 | TF_RETURN_IF_ERROR(c->WithRank(c->input(1), rank, &filter_shape)); |
| 727 | TF_RETURN_IF_ERROR( |
| 728 | CheckFormatConstraintsOnShape(data_format, filter_shape, "filter", c)); |
| 729 | |
| 730 | std::vector<int32> dilations; |
| 731 | TF_RETURN_IF_ERROR(c->GetAttr("dilations", &dilations)); |
| 732 | |
| 733 | if (dilations.size() != 4) { |
| 734 | return errors::InvalidArgument( |
| 735 | "Conv2D requires the dilation attribute to contain 4 values, but got: ", |
| 736 | dilations.size()); |
| 737 | } |
| 738 | |
| 739 | std::vector<int32> strides; |
| 740 | TF_RETURN_IF_ERROR(c->GetAttr("strides", &strides)); |
| 741 | |
| 742 | // strides.size() should be 4 (NCHW) even if the input is 5 (NCHW_VECT_C). |
| 743 | if (strides.size() != 4) { |
| 744 | return errors::InvalidArgument("Conv2D on data format ", data_format_str, |
| 745 | " requires the stride attribute to contain" |
| 746 | " 4 values, but got: ", |
| 747 | strides.size()); |
| 748 | } |
| 749 | |
| 750 | const int32 stride_rows = GetTensorDim(strides, data_format, 'H'); |
| 751 | const int32 stride_cols = GetTensorDim(strides, data_format, 'W'); |
| 752 | const int32 dilation_rows = GetTensorDim(dilations, data_format, 'H'); |
no test coverage detected