| 73 | |
| 74 | template <class Shape> |
| 75 | Status TensorShapeBase<Shape>::IsValidShape(const TensorShapeProto& proto) { |
| 76 | // NOTE(irving): Unfortunately, TensorShape allows parsing protos with |
| 77 | // unknown_shape() set, and it seems hard to remove this without backwards |
| 78 | // compatibility issues. |
| 79 | if (kIsPartial && proto.unknown_rank()) { |
| 80 | if (proto.dim_size() > 0) { |
| 81 | return errors::InvalidArgument( |
| 82 | "An unknown shape must not have any dimensions set."); |
| 83 | } |
| 84 | return Status::OK(); |
| 85 | } |
| 86 | int64 num_elements = 1; |
| 87 | if (proto.dim().size() > MaxDimensions()) { |
| 88 | return errors::InvalidArgument("Shape ", DebugString(proto), |
| 89 | " has too many dimensions"); |
| 90 | } |
| 91 | for (const auto& d : proto.dim()) { |
| 92 | if (d.size() < (kIsPartial ? -1 : 0)) { |
| 93 | if (kIsPartial) { |
| 94 | return errors::InvalidArgument( |
| 95 | "Shape ", DebugString(proto), |
| 96 | " has dimensions with values below -1 (where -1 means unknown)"); |
| 97 | } else { |
| 98 | return errors::InvalidArgument("Shape ", DebugString(proto), |
| 99 | " is not fully defined"); |
| 100 | } |
| 101 | } |
| 102 | if (d.size() == -1) { |
| 103 | num_elements = -1; |
| 104 | } else if (!kIsPartial || num_elements >= 0) { |
| 105 | num_elements = MultiplyWithoutOverflow(num_elements, d.size()); |
| 106 | if (num_elements < 0) { |
| 107 | return errors::InvalidArgument( |
| 108 | "Shape ", DebugString(proto), |
| 109 | " is too large (more than 2**63 - 1 entries)"); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | return Status::OK(); |
| 114 | } |
| 115 | |
| 116 | template <class Shape> |
| 117 | TensorShapeBase<Shape>::TensorShapeBase(const TensorShapeProto& proto) { |
nothing calls this directly
no test coverage detected