| 1521 | } |
| 1522 | |
| 1523 | Status ReductionShape(InferenceContext* c) { |
| 1524 | ShapeHandle input = c->input(0); |
| 1525 | |
| 1526 | ShapeHandle indices; |
| 1527 | // Older versions of TensorFlow accidentally allowed higher rank tensors like |
| 1528 | // [[1,2]] or [[1],[2]] to represent axis=[1,2]. |
| 1529 | if (c->graph_def_version() < 21) { |
| 1530 | indices = c->input(1); |
| 1531 | } else { |
| 1532 | TF_RETURN_IF_ERROR(c->WithRankAtMost(c->input(1), 1, &indices)); |
| 1533 | } |
| 1534 | |
| 1535 | bool keep_dims; |
| 1536 | TF_RETURN_IF_ERROR(c->GetAttr("keep_dims", &keep_dims)); |
| 1537 | |
| 1538 | const Tensor* reduction_indices_t = c->input_tensor(1); |
| 1539 | if (reduction_indices_t == nullptr || !c->RankKnown(input)) { |
| 1540 | // If we do not have the reduction values at runtime, or the |
| 1541 | // rank of the input, we don't know the output shape. |
| 1542 | |
| 1543 | if (keep_dims && c->RankKnown(input)) { |
| 1544 | // output rank matches input input if <keep_dims>. |
| 1545 | c->set_output(0, c->UnknownShapeOfRank(c->Rank(input))); |
| 1546 | return Status::OK(); |
| 1547 | } else { |
| 1548 | return shape_inference::UnknownShape(c); |
| 1549 | } |
| 1550 | } |
| 1551 | |
| 1552 | const int32 input_rank = c->Rank(input); |
| 1553 | std::set<int64> true_indices; |
| 1554 | if (reduction_indices_t->dtype() == DataType::DT_INT32) { |
| 1555 | TF_RETURN_IF_ERROR(ReductionShapeHelper<int32>(reduction_indices_t, |
| 1556 | input_rank, &true_indices)); |
| 1557 | } else if (reduction_indices_t->dtype() == DataType::DT_INT64) { |
| 1558 | TF_RETURN_IF_ERROR(ReductionShapeHelper<int64>(reduction_indices_t, |
| 1559 | input_rank, &true_indices)); |
| 1560 | } else { |
| 1561 | return errors::InvalidArgument( |
| 1562 | "reduction_indices can only be int32 or int64"); |
| 1563 | } |
| 1564 | |
| 1565 | std::vector<DimensionHandle> dims; |
| 1566 | for (int i = 0; i < input_rank; ++i) { |
| 1567 | if (true_indices.count(i) > 0) { |
| 1568 | if (keep_dims) { |
| 1569 | dims.emplace_back(c->MakeDim(1)); |
| 1570 | } |
| 1571 | } else { |
| 1572 | dims.emplace_back(c->Dim(input, i)); |
| 1573 | } |
| 1574 | } |
| 1575 | |
| 1576 | c->set_output(0, c->MakeShape(dims)); |
| 1577 | return Status::OK(); |
| 1578 | } |
| 1579 | |
| 1580 | Status ConcatShapeHelper(InferenceContext* c, int start_value_index, |
nothing calls this directly
no test coverage detected