| 462 | namespace { |
| 463 | |
| 464 | Status CommonFusedConvCalculations(InferenceContext* c, bool has_resize) { |
| 465 | ShapeHandle input; |
| 466 | TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 4, &input)); |
| 467 | |
| 468 | ShapeHandle resized = input; |
| 469 | int paddings_index = 1; |
| 470 | int filter_index = 2; |
| 471 | if (has_resize) { |
| 472 | paddings_index = 2; |
| 473 | filter_index = 3; |
| 474 | |
| 475 | ShapeHandle unused_size; |
| 476 | TF_RETURN_IF_ERROR(c->Merge(c->input(1), c->Vector(2), &unused_size)); |
| 477 | |
| 478 | const Tensor* size = c->input_tensor(1); |
| 479 | DimensionHandle new_height = c->UnknownDim(); |
| 480 | DimensionHandle new_width = c->UnknownDim(); |
| 481 | if (size != nullptr) { |
| 482 | new_height = c->MakeDim(size->flat<int32>()(0)); |
| 483 | new_width = c->MakeDim(size->flat<int32>()(1)); |
| 484 | } |
| 485 | TF_RETURN_IF_ERROR(c->ReplaceDim(resized, 1, new_height, &resized)); |
| 486 | TF_RETURN_IF_ERROR(c->ReplaceDim(resized, 2, new_width, &resized)); |
| 487 | } |
| 488 | |
| 489 | ShapeHandle paddings; |
| 490 | TF_RETURN_IF_ERROR(c->WithRank(c->input(paddings_index), 2, &paddings)); |
| 491 | TF_RETURN_IF_ERROR( |
| 492 | c->WithRank(resized, c->Value(c->Dim(paddings, 0)), &resized)); |
| 493 | TF_RETURN_IF_ERROR( |
| 494 | c->Merge(paddings, c->Matrix(c->Rank(resized), 2), &paddings)); |
| 495 | |
| 496 | const Tensor* paddings_t = c->input_tensor(paddings_index); |
| 497 | ShapeHandle padded; |
| 498 | if (paddings_t != nullptr) { |
| 499 | std::vector<DimensionHandle> output_dims; |
| 500 | for (int i = 0; i < 4; ++i) { |
| 501 | DimensionHandle dim = c->Dim(resized, i); |
| 502 | int64 p0 = static_cast<int64>(paddings_t->matrix<int32>()(i, 0)); |
| 503 | int64 p1 = static_cast<int64>(paddings_t->matrix<int32>()(i, 1)); |
| 504 | if (p0 < 0 || p1 < 0) { |
| 505 | return errors::InvalidArgument("Paddings must be non-negative"); |
| 506 | } |
| 507 | |
| 508 | TF_RETURN_IF_ERROR(c->Add(dim, p0 + p1, &dim)); |
| 509 | output_dims.push_back(dim); |
| 510 | } |
| 511 | padded = c->MakeShape(output_dims); |
| 512 | } else { |
| 513 | padded = c->UnknownShapeOfRank(4); |
| 514 | } |
| 515 | |
| 516 | // Work out the convolution's effect with 'padded' as the input. |
| 517 | ShapeHandle filter; |
| 518 | TF_RETURN_IF_ERROR(c->WithRank(c->input(filter_index), 4, &filter)); |
| 519 | std::vector<int32> strides; |
| 520 | TF_RETURN_IF_ERROR(c->GetAttr("strides", &strides)); |
| 521 | if (strides.size() != 4) { |
no test coverage detected