The first input is [...,M,N] and second input is either [...,M,K] or [...,M]. Output is [...,N,K] or [...,N]. If , then input is [...,M,M].
| 50 | // The first input is [...,M,N] and second input is either [...,M,K] or [...,M]. |
| 51 | // Output is [...,N,K] or [...,N]. If <square>, then input is [...,M,M]. |
| 52 | Status MatrixSolveShapeFn(InferenceContext* c, bool square) { |
| 53 | ShapeHandle lhs; |
| 54 | ShapeHandle rhs; |
| 55 | if (square) { |
| 56 | TF_RETURN_IF_ERROR(MakeBatchSquareMatrix(c, c->input(0), &lhs)); |
| 57 | } else { |
| 58 | TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(0), 2, &lhs)); |
| 59 | } |
| 60 | TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(1), 2, &rhs)); |
| 61 | |
| 62 | ShapeHandle lhs_batch_shape; |
| 63 | ShapeHandle rhs_batch_shape; |
| 64 | // Make the common batch subshape. |
| 65 | TF_RETURN_IF_ERROR(c->Subshape(lhs, 0, -2, &lhs_batch_shape)); |
| 66 | TF_RETURN_IF_ERROR(c->Subshape(rhs, 0, -2, &rhs_batch_shape)); |
| 67 | // Make sure the batch dimensions match between lhs and rhs. |
| 68 | TF_RETURN_IF_ERROR( |
| 69 | c->Merge(lhs_batch_shape, rhs_batch_shape, &lhs_batch_shape)); |
| 70 | |
| 71 | DimensionHandle m; |
| 72 | // lhs and rhs have the same value for m to be compatible. |
| 73 | TF_RETURN_IF_ERROR(c->Merge(c->Dim(lhs, -2), c->Dim(rhs, -2), &m)); |
| 74 | DimensionHandle n = c->Dim(lhs, -1); |
| 75 | if (square) { |
| 76 | TF_RETURN_IF_ERROR(c->Merge(m, n, &n)); |
| 77 | } |
| 78 | |
| 79 | ShapeHandle out; |
| 80 | // Build final shape (batch_shape + n + k) in <out>. |
| 81 | TF_RETURN_IF_ERROR(c->Concatenate(lhs_batch_shape, c->Vector(n), &out)); |
| 82 | TF_RETURN_IF_ERROR(c->Concatenate(out, c->Vector(c->Dim(rhs, -1)), &out)); |
| 83 | c->set_output(0, out); |
| 84 | return Status::OK(); |
| 85 | } |
| 86 | |
| 87 | // Input is [...,N,N]. Outputs are: |
| 88 | // [...,N];[0], if compute_v is false, |
no test coverage detected