| 446 | } |
| 447 | |
| 448 | Status BatchMatMulV2Shape(shape_inference::InferenceContext* c) { |
| 449 | ShapeHandle a_shape; |
| 450 | ShapeHandle b_shape; |
| 451 | TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(0), 2, &a_shape)); |
| 452 | TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(1), 2, &b_shape)); |
| 453 | |
| 454 | // Determine output rows and columns. |
| 455 | bool adj_x; |
| 456 | bool adj_y; |
| 457 | TF_RETURN_IF_ERROR(c->GetAttr("adj_x", &adj_x)); |
| 458 | TF_RETURN_IF_ERROR(c->GetAttr("adj_y", &adj_y)); |
| 459 | DimensionHandle output_rows = c->Dim(a_shape, adj_x ? -1 : -2); |
| 460 | DimensionHandle output_cols = c->Dim(b_shape, adj_y ? -2 : -1); |
| 461 | |
| 462 | // Inner dimensions should be compatible. |
| 463 | DimensionHandle inner_merged; |
| 464 | TF_RETURN_IF_ERROR(c->Merge(c->Dim(a_shape, adj_x ? -2 : -1), |
| 465 | c->Dim(b_shape, adj_y ? -1 : -2), &inner_merged)); |
| 466 | |
| 467 | // Batch dimensions should broadcast with each other. |
| 468 | ShapeHandle a_batch_shape; |
| 469 | ShapeHandle b_batch_shape; |
| 470 | ShapeHandle output_batch_shape; |
| 471 | TF_RETURN_IF_ERROR(c->Subshape(a_shape, 0, -2, &a_batch_shape)); |
| 472 | TF_RETURN_IF_ERROR(c->Subshape(b_shape, 0, -2, &b_batch_shape)); |
| 473 | |
| 474 | TF_RETURN_IF_ERROR(BroadcastBinaryOpOutputShapeFnHelper( |
| 475 | c, a_batch_shape, b_batch_shape, true, &output_batch_shape)); |
| 476 | |
| 477 | ShapeHandle output_shape; |
| 478 | TF_RETURN_IF_ERROR(c->Concatenate( |
| 479 | output_batch_shape, c->Matrix(output_rows, output_cols), &output_shape)); |
| 480 | |
| 481 | c->set_output(0, output_shape); |
| 482 | return Status::OK(); |
| 483 | } |
| 484 | |
| 485 | Status BatchMatMulShape(shape_inference::InferenceContext* c) { |
| 486 | ShapeHandle a_shape; |
nothing calls this directly
no test coverage detected