| 2455 | } |
| 2456 | |
| 2457 | Status SpaceToBatchShapeHelper(InferenceContext* c, ShapeHandle input_shape, |
| 2458 | ShapeHandle block_shape_shape, |
| 2459 | const Tensor* block_shape_t, |
| 2460 | ShapeHandle paddings_shape, |
| 2461 | const Tensor* paddings_t) { |
| 2462 | if (c->Rank(block_shape_shape) != 1) { |
| 2463 | return errors::InvalidArgument("block_shape must have rank 1."); |
| 2464 | } |
| 2465 | |
| 2466 | const DimensionHandle num_block_dims_handle = c->Dim(block_shape_shape, 0); |
| 2467 | if (!c->ValueKnown(num_block_dims_handle)) { |
| 2468 | return errors::InvalidArgument("block_shape must have known size."); |
| 2469 | } |
| 2470 | |
| 2471 | const int64 num_block_dims = c->Value(num_block_dims_handle); |
| 2472 | |
| 2473 | TF_RETURN_IF_ERROR( |
| 2474 | c->WithRankAtLeast(input_shape, num_block_dims + 1, &input_shape)); |
| 2475 | |
| 2476 | TF_RETURN_IF_ERROR( |
| 2477 | c->Merge(paddings_shape, c->Matrix(num_block_dims, 2), &paddings_shape)); |
| 2478 | |
| 2479 | DimensionHandle batch_size = c->Dim(input_shape, 0); |
| 2480 | std::vector<int64> block_shape_vec; |
| 2481 | if (block_shape_t) { |
| 2482 | block_shape_vec = GetFlatInt64(*block_shape_t); |
| 2483 | for (int64 dim = 0; dim < num_block_dims; ++dim) { |
| 2484 | const int64 block_shape_value = block_shape_vec[dim]; |
| 2485 | if (block_shape_value < 1) { |
| 2486 | return errors::InvalidArgument("block_shape must be positive"); |
| 2487 | } |
| 2488 | if (c->ValueKnown(batch_size)) { |
| 2489 | TF_RETURN_IF_ERROR( |
| 2490 | c->Multiply(batch_size, block_shape_value, &batch_size)); |
| 2491 | } else { |
| 2492 | batch_size = c->UnknownDim(); |
| 2493 | } |
| 2494 | } |
| 2495 | } else if (num_block_dims > 0) { |
| 2496 | batch_size = c->UnknownDim(); |
| 2497 | } |
| 2498 | |
| 2499 | std::vector<DimensionHandle> output_dims{batch_size}; |
| 2500 | output_dims.resize(num_block_dims + 1, c->UnknownDim()); |
| 2501 | |
| 2502 | if (paddings_t) { |
| 2503 | const std::vector<int64> paddings_vec = GetFlatInt64(*paddings_t); |
| 2504 | for (int64 dim = 0; dim < num_block_dims; ++dim) { |
| 2505 | const int64 pad_start = paddings_vec[dim * 2], |
| 2506 | pad_end = paddings_vec[dim * 2 + 1]; |
| 2507 | if (pad_start < 0 || pad_end < 0) { |
| 2508 | return errors::InvalidArgument("paddings cannot be negative"); |
| 2509 | } |
| 2510 | if (block_shape_t) { |
| 2511 | DimensionHandle padded_size; |
| 2512 | TF_RETURN_IF_ERROR( |
| 2513 | c->Add(c->Dim(input_shape, dim + 1), pad_start, &padded_size)); |
| 2514 | TF_RETURN_IF_ERROR(c->Add(padded_size, pad_end, &padded_size)); |
no test coverage detected