@@ -75,67 +75,68 @@ LogicalResult verifyElementwiseByOperandImpl(
7575 ElementwiseByOperandOpInterface opInterface) {
7676 Operation* op = opInterface.getOperation ();
7777
78- auto typeToShapeStr = [](Type type) {
79- if (auto rankedTensorType = dyn_cast<RankedTensorType>(type)) {
80- std::string shapeStr = " (" ;
81- for (auto dim : rankedTensorType.getShape ()) {
82- shapeStr += std::to_string (dim) + " ," ;
83- }
84- shapeStr += " )" ;
85- return shapeStr;
86- }
87- return std::string (" (not statically ranked)" );
78+ auto typeToShapeStr = [](ArrayRef<int64_t > shape) {
79+ return " (" +
80+ llvm::join (
81+ llvm::map_range (shape,
82+ [](int64_t dim) { return std::to_string (dim); }),
83+ " , " ) +
84+ " )" ;
8885 };
8986
90- std::optional<TensorType> tensorType;
91- int64_t operandIndex = 0 ;
87+ std::optional<SmallVector<int64_t >> mappedShape;
88+ int64_t firstMappableOperandIndex = -1 ;
89+
9290 for (auto [i, operand] : llvm::enumerate (op->getOperands ())) {
9391 auto thisTensorType = dyn_cast<TensorType>(operand.getType ());
94- if (!thisTensorType)
95- // Non-tensor types are acceptable, and need not be specified as mappable
96- // or not mappable by the interface.
97- continue ;
92+ if (!thisTensorType) continue ;
9893
9994 if (opInterface.operandIsMappable (i)) {
100- if (!tensorType) {
101- tensorType = thisTensorType;
102- operandIndex = i;
95+ SmallVector<int64_t > thisMappedShape;
96+ for (int dim : opInterface.mappedDimensionsForOperand (i)) {
97+ thisMappedShape.push_back (thisTensorType.getDimSize (dim));
98+ }
99+
100+ if (!mappedShape) {
101+ mappedShape = thisMappedShape;
102+ firstMappableOperandIndex = i;
103103 continue ;
104104 }
105105
106- if (thisTensorType. getShape () != tensorType-> getShape () ) {
106+ if (thisMappedShape != *mappedShape ) {
107107 return op->emitOpError ()
108- << " expected all mappable operands to have the same shape, "
109- << " but found shape " << typeToShapeStr (*tensorType)
110- << " at operand " << operandIndex << " and "
111- << typeToShapeStr (thisTensorType) << " at operand " << i;
108+ << " expected all mappable operands to have the same mapped "
109+ " shape, but found mapped shape "
110+ << typeToShapeStr (*mappedShape) << " at operand "
111+ << firstMappableOperandIndex << " and "
112+ << typeToShapeStr (thisMappedShape) << " at operand " << i;
112113 }
113114 }
114115 }
115116
116117 for (auto [i, result] : llvm::enumerate (op->getResults ())) {
117118 auto thisTensorType = dyn_cast<TensorType>(result.getType ());
118- if (tensorType && !thisTensorType)
119+ if (mappedShape && !mappedShape-> empty () && !thisTensorType)
119120 return op->emitOpError ()
120- << " expected all results operands to have the same tensor shape, "
121- << " as the mappable input operands, but found shape "
122- << typeToShapeStr (*tensorType) << " at operand " << operandIndex
123- << " and result " << i << " of non-tensor type "
124- << result.getType ();
121+ << " expected all results to be tensors with shape "
122+ << typeToShapeStr (*mappedShape)
123+ << " due to mappable operands, but result " << i
124+ << " is of non-tensor type " << result.getType ();
125125
126- if (!tensorType && thisTensorType)
126+ if (!mappedShape && thisTensorType)
127127 return op->emitOpError ()
128- << " No operands were tensor typed, but result at index " << i
129- << " is a tensor of shape " << typeToShapeStr (thisTensorType);
128+ << " No operands were mappable, but result at index " << i
129+ << " is a tensor of shape "
130+ << typeToShapeStr (thisTensorType.getShape ());
130131
131- if (tensorType && thisTensorType &&
132- thisTensorType.getShape () != tensorType-> getShape ( )) {
132+ if (mappedShape && thisTensorType &&
133+ thisTensorType.getShape () != ArrayRef< int64_t >(*mappedShape )) {
133134 return op->emitOpError ()
134135 << " expected all tensor results to have the same shape as "
135136 " mappable operands, but found shape "
136- << typeToShapeStr (*tensorType ) << " at operand " << operandIndex
137- << " and shape " << typeToShapeStr (thisTensorType) << " at result "
138- << i;
137+ << typeToShapeStr (*mappedShape ) << " at operand "
138+ << firstMappableOperandIndex << " and shape "
139+ << typeToShapeStr (thisTensorType. getShape ()) << " at result " << i;
139140 }
140141 }
141142
0 commit comments