| 681 | } |
| 682 | |
| 683 | bool ShapesAgreeUpToBroadcasting(const Shape& shape0, const Shape& shape1) { |
| 684 | CheckNonEmptyShapeDimensions(shape0); |
| 685 | CheckNonEmptyShapeDimensions(shape1); |
| 686 | |
| 687 | const Shape* longer = &shape0; |
| 688 | const Shape* shorter = &shape1; |
| 689 | if (shape1.dimensions_count() > shape0.dimensions_count()) { |
| 690 | longer = &shape1; |
| 691 | shorter = &shape0; |
| 692 | } |
| 693 | |
| 694 | // Walk dimensions back to front until we run out of dimensions in the shorter |
| 695 | // shape. |
| 696 | int longer_index = longer->dimensions_count() - 1; |
| 697 | int shorter_index = shorter->dimensions_count() - 1; |
| 698 | while (shorter_index >= 0) { |
| 699 | const int d_long = longer->dims(longer_index); |
| 700 | const int d_short = shorter->dims(shorter_index); |
| 701 | // Broadcasting fails if the dimensions are different *and* neither is 1. |
| 702 | if ((d_long != d_short) && (d_long != 1) && (d_short != 1)) { |
| 703 | return false; |
| 704 | } |
| 705 | longer_index--; |
| 706 | shorter_index--; |
| 707 | } |
| 708 | return true; |
| 709 | } |
| 710 | |
| 711 | bool ShapesAgreeUpToExtending(const Shape& shape0, const Shape& shape1) { |
| 712 | CheckNonEmptyShapeDimensions(shape0); |