| 1237 | } |
| 1238 | |
| 1239 | Status MaxPoolShape(shape_inference::InferenceContext* c) { |
| 1240 | string data_format_str; |
| 1241 | TensorFormat data_format; |
| 1242 | Status s = c->GetAttr("data_format", &data_format_str); |
| 1243 | if (s.ok()) { |
| 1244 | FormatFromString(data_format_str, &data_format); |
| 1245 | } else { |
| 1246 | data_format = FORMAT_NHWC; |
| 1247 | } |
| 1248 | |
| 1249 | const int rank = (data_format == FORMAT_NCHW_VECT_C) ? 5 : 4; |
| 1250 | ShapeHandle input_shape; |
| 1251 | TF_RETURN_IF_ERROR(c->WithRank(c->input(0), rank, &input_shape)); |
| 1252 | |
| 1253 | TF_RETURN_IF_ERROR( |
| 1254 | CheckFormatConstraintsOnShape(data_format, input_shape, "input", c)); |
| 1255 | |
| 1256 | std::vector<int32> strides; |
| 1257 | TF_RETURN_IF_ERROR(c->GetAttr("strides", &strides)); |
| 1258 | if (strides.size() != 4) { |
| 1259 | return errors::InvalidArgument( |
| 1260 | "MaxPool requires the stride attribute to contain 4 values, but got: ", |
| 1261 | strides.size()); |
| 1262 | } |
| 1263 | |
| 1264 | std::vector<int32> kernel_sizes; |
| 1265 | TF_RETURN_IF_ERROR(c->GetAttr("ksize", &kernel_sizes)); |
| 1266 | if (kernel_sizes.size() != 4) { |
| 1267 | return errors::InvalidArgument( |
| 1268 | "MaxPool requires the ksize attribute to contain 4 values, but got: ", |
| 1269 | kernel_sizes.size()); |
| 1270 | } |
| 1271 | |
| 1272 | int32 stride_depth = GetTensorDim(strides, data_format, 'C'); |
| 1273 | int32 stride_rows = GetTensorDim(strides, data_format, 'H'); |
| 1274 | int32 stride_cols = GetTensorDim(strides, data_format, 'W'); |
| 1275 | int32 kernel_depth = GetTensorDim(kernel_sizes, data_format, 'C'); |
| 1276 | int32 kernel_rows = GetTensorDim(kernel_sizes, data_format, 'H'); |
| 1277 | int32 kernel_cols = GetTensorDim(kernel_sizes, data_format, 'W'); |
| 1278 | |
| 1279 | constexpr int num_spatial_dims = 2; |
| 1280 | DimensionHandle batch_size_dim = c->Dim( |
| 1281 | input_shape, GetTensorDimIndex<num_spatial_dims>(data_format, 'N')); |
| 1282 | DimensionHandle in_rows_dim = c->Dim( |
| 1283 | input_shape, GetTensorDimIndex<num_spatial_dims>(data_format, 'H')); |
| 1284 | DimensionHandle in_cols_dim = c->Dim( |
| 1285 | input_shape, GetTensorDimIndex<num_spatial_dims>(data_format, 'W')); |
| 1286 | DimensionHandle in_depth_dim = c->Dim( |
| 1287 | input_shape, GetTensorDimIndex<num_spatial_dims>(data_format, 'C')); |
| 1288 | |
| 1289 | Padding padding; |
| 1290 | TF_RETURN_IF_ERROR(c->GetAttr("padding", &padding)); |
| 1291 | |
| 1292 | ShapeHandle output_shape; |
| 1293 | DimensionHandle output_rows, output_cols, output_depth; |
| 1294 | TF_RETURN_IF_ERROR(GetWindowedOutputSizeFromDims( |
| 1295 | c, in_rows_dim, kernel_rows, stride_rows, padding, &output_rows)); |
| 1296 | TF_RETURN_IF_ERROR(GetWindowedOutputSizeFromDims( |
no test coverage detected