| 988 | } |
| 989 | |
| 990 | void DenseArrayToStringHelper(const LiteralBase& literal, |
| 991 | const ShapeIndex& shape_index, bool print_shape, |
| 992 | bool print_layout, std::vector<string>* pieces) { |
| 993 | const Shape& subshape = ShapeUtil::GetSubshape(literal.shape(), shape_index); |
| 994 | int64 rank = subshape.rank(); |
| 995 | |
| 996 | std::function<void(absl::Span<const int64> dimensions, std::vector<int64>*)> |
| 997 | to_string_recursive = [&](absl::Span<const int64> dimensions, |
| 998 | std::vector<int64>* accum_indices) { |
| 999 | // dimensions.size() decreases by 1 at each recursive call, |
| 1000 | // and accum_indices->size() increases by 1. |
| 1001 | // Their sum is equal to the rank of the tensor. |
| 1002 | CHECK_EQ(rank, dimensions.size() + accum_indices->size()); |
| 1003 | |
| 1004 | auto brace_to_string = [&](string brace) -> string { |
| 1005 | // Handle 1D tensor |
| 1006 | if (rank == 1) { |
| 1007 | return brace; |
| 1008 | } |
| 1009 | // Handle the innermost tensor of a 2D+ tensor. |
| 1010 | if (dimensions.size() == 1 && brace == "{") { |
| 1011 | return StrCat(" ", brace, dimensions[0] <= 1 ? "" : " "); |
| 1012 | } |
| 1013 | if (dimensions.size() == 1 && brace == "}") { |
| 1014 | return StrCat(dimensions[0] <= 1 ? "" : " ", brace); |
| 1015 | } |
| 1016 | // Handle the non-innermost tensors of a 2D+ tensor. |
| 1017 | if (brace == "{") { |
| 1018 | if (rank > 3 && !accum_indices->empty() && |
| 1019 | accum_indices->size() < rank) { |
| 1020 | int index = accum_indices->size() - 1; |
| 1021 | int value = accum_indices->back(); |
| 1022 | return StrCat(brace, " /*i", index, "=", value, "*/\n"); |
| 1023 | } |
| 1024 | return StrCat(brace, "\n"); |
| 1025 | } |
| 1026 | return StrCat("\n", brace); |
| 1027 | }; |
| 1028 | |
| 1029 | if (dimensions.empty()) { |
| 1030 | // Display predicates as 0s and 1s so that the string is more dense. |
| 1031 | string elem; |
| 1032 | if (subshape.element_type() == PRED && rank > 0) { |
| 1033 | elem = literal.Get<bool>(*accum_indices, shape_index) ? "1" : "0"; |
| 1034 | } else { |
| 1035 | elem = literal.GetAsString(*accum_indices, shape_index); |
| 1036 | } |
| 1037 | pieces->push_back(elem); |
| 1038 | } else { |
| 1039 | pieces->push_back(brace_to_string("{")); |
| 1040 | for (int i = 0; i < dimensions[0]; ++i) { |
| 1041 | std::vector<int64> cloned_indices(*accum_indices); |
| 1042 | cloned_indices.push_back(i); |
| 1043 | to_string_recursive(dimensions.subspan(1), &cloned_indices); |
| 1044 | if (i < dimensions[0] - 1) { |
| 1045 | pieces->push_back(","); |
| 1046 | pieces->push_back(dimensions.size() > 1 ? "\n" : " "); |
| 1047 | } |
no test coverage detected