static */
| 501 | } |
| 502 | |
| 503 | /* static */ StatusOr<Shape> ShapeInference::InferPadShape( |
| 504 | const Shape& operand_shape, const Shape& padding_value_shape, |
| 505 | const PaddingConfig& padding_config) { |
| 506 | if (!operand_shape.IsArray()) { |
| 507 | return InvalidArgument( |
| 508 | "Pad operation does not support tuple-shape operands."); |
| 509 | } |
| 510 | if (!ShapeUtil::IsScalar(padding_value_shape)) { |
| 511 | return InvalidArgument( |
| 512 | "Pad operation does not support non-scalar padding values."); |
| 513 | } |
| 514 | if (operand_shape.rank() != padding_config.dimensions_size()) { |
| 515 | return InvalidArgument( |
| 516 | "The rank of the operand and the padding configuration do not match: " |
| 517 | "%s vs %s.", |
| 518 | ShapeUtil::HumanString(operand_shape), |
| 519 | padding_config.ShortDebugString()); |
| 520 | } |
| 521 | if (!ShapeUtil::SameElementTypeIgnoringFpPrecision(operand_shape, |
| 522 | padding_value_shape)) { |
| 523 | return InvalidArgument( |
| 524 | "The element types of the operands to Pad do not match."); |
| 525 | } |
| 526 | if (absl::c_any_of(padding_config.dimensions(), |
| 527 | [](const PaddingConfig::PaddingConfigDimension& p) { |
| 528 | return p.interior_padding() < 0; |
| 529 | })) { |
| 530 | return InvalidArgument("Interior padding cannot be negative: %s", |
| 531 | padding_config.ShortDebugString()); |
| 532 | } |
| 533 | |
| 534 | if (!padding_value_shape.is_static()) { |
| 535 | return InvalidArgument("Dynamic padding value is not supported"); |
| 536 | } |
| 537 | |
| 538 | std::vector<int64> dimensions(operand_shape.rank()); |
| 539 | std::vector<bool> is_dynamic(operand_shape.rank()); |
| 540 | for (int64 i = 0; i < operand_shape.dimensions_size(); ++i) { |
| 541 | const auto& p = padding_config.dimensions(i); |
| 542 | if (operand_shape.is_dynamic_dimension(i) && p.edge_padding_high() != 0 && |
| 543 | p.edge_padding_low() != 0 && p.interior_padding() != 0) { |
| 544 | return InvalidArgument( |
| 545 | "Dynamic dimension on padding dimension is not supported."); |
| 546 | } |
| 547 | dimensions[i] = operand_shape.dimensions(i) + p.edge_padding_low() + |
| 548 | p.edge_padding_high() + |
| 549 | std::max<int64>(operand_shape.dimensions(i) - 1, 0LL) * |
| 550 | p.interior_padding(); |
| 551 | if (dimensions[i] < 0) { |
| 552 | return InvalidArgument("Padding result in negative size for dimension %d", |
| 553 | i); |
| 554 | } |
| 555 | is_dynamic[i] = operand_shape.is_dynamic_dimension(i); |
| 556 | } |
| 557 | |
| 558 | return ShapeUtil::MakeShape( |
| 559 | ShapeUtil::HigherPrecisionElementType(operand_shape, padding_value_shape), |
| 560 | dimensions, is_dynamic); |
nothing calls this directly
no test coverage detected