shape ::= shape_val_ shape ::= '(' tuple_elements ')' tuple_elements ::= /*empty*/ ::= shape (',' shape)
| 3733 | // ::= /*empty*/ |
| 3734 | // ::= shape (',' shape)* |
| 3735 | bool HloParserImpl::ParseShape(Shape* result) { |
| 3736 | if (EatIfPresent(TokKind::kLparen)) { // Tuple |
| 3737 | std::vector<Shape> shapes; |
| 3738 | if (lexer_.GetKind() == TokKind::kRparen) { |
| 3739 | /*empty*/ |
| 3740 | } else { |
| 3741 | // shape (',' shape)* |
| 3742 | do { |
| 3743 | shapes.emplace_back(); |
| 3744 | if (!ParseShape(&shapes.back())) { |
| 3745 | return false; |
| 3746 | } |
| 3747 | } while (EatIfPresent(TokKind::kComma)); |
| 3748 | } |
| 3749 | *result = ShapeUtil::MakeTupleShape(shapes); |
| 3750 | return ParseToken(TokKind::kRparen, "expects ')' at the end of tuple."); |
| 3751 | } |
| 3752 | |
| 3753 | if (lexer_.GetKind() != TokKind::kPrimitiveType) { |
| 3754 | return TokenError(absl::StrCat("expected primitive type, saw ", |
| 3755 | TokKindToString(lexer_.GetKind()))); |
| 3756 | } |
| 3757 | PrimitiveType primitive_type = lexer_.GetPrimitiveTypeVal(); |
| 3758 | lexer_.Lex(); |
| 3759 | |
| 3760 | // Each element contains a dimension size and a bool indicating whether this |
| 3761 | // is a dynamic dimension. |
| 3762 | std::vector<int64> dimension_sizes; |
| 3763 | std::vector<bool> dynamic_dimensions; |
| 3764 | if (!ParseDimensionSizes(&dimension_sizes, &dynamic_dimensions)) { |
| 3765 | return false; |
| 3766 | } |
| 3767 | result->set_element_type(primitive_type); |
| 3768 | for (int i = 0; i < dimension_sizes.size(); ++i) { |
| 3769 | result->add_dimensions(dimension_sizes[i]); |
| 3770 | result->set_dynamic_dimension(i, dynamic_dimensions[i]); |
| 3771 | } |
| 3772 | LayoutUtil::SetToDefaultLayout(result); |
| 3773 | |
| 3774 | // We need to lookahead to see if a following open brace is the start of a |
| 3775 | // layout. The specific problematic case is: |
| 3776 | // |
| 3777 | // ENTRY %foo (x: f32[42]) -> f32[123] { |
| 3778 | // ... |
| 3779 | // } |
| 3780 | // |
| 3781 | // The open brace could either be the start of a computation or the start of a |
| 3782 | // layout for the f32[123] shape. We consider it the start of a layout if the |
| 3783 | // next token after the open brace is an integer or a colon. |
| 3784 | if (lexer_.GetKind() == TokKind::kLbrace && |
| 3785 | (lexer_.LookAhead() == TokKind::kInt || |
| 3786 | lexer_.LookAhead() == TokKind::kColon)) { |
| 3787 | Layout layout; |
| 3788 | if (!ParseLayout(&layout)) { |
| 3789 | return false; |
| 3790 | } |
| 3791 | if (layout.minor_to_major_size() != result->rank()) { |
| 3792 | return Error( |
nothing calls this directly
no test coverage detected