Skip to content

Commit c563af4

Browse files
Temporary revert "Step to resolve"
This reverts commit d8a0fe8.
1 parent d8a0fe8 commit c563af4

File tree

6 files changed

+89
-108
lines changed

6 files changed

+89
-108
lines changed

mlir/include/mlir/Interfaces/IndexingMapOpInterface.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@
1414
#include "mlir/IR/BuiltinTypes.h"
1515
#include "mlir/IR/OpDefinition.h"
1616

17-
namespace mlir {
18-
namespace detail {
19-
/// Verify that `op` conforms to the invariants of StructuredOpInterface
20-
LogicalResult verifyIndexingMapOpInterface(Operation *op);
21-
} // namespace detail
22-
} // namespace mlir
23-
2417
/// Include the generated interface declarations.
2518
#include "mlir/Interfaces/IndexingMapOpInterface.h.inc"
2619

mlir/include/mlir/Interfaces/IndexingMapOpInterface.td

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,23 @@ def IndexingMapOpInterface : OpInterface<"IndexingMapOpInterface"> {
8383
return concatAffineMaps(maps, $_op.getContext());
8484
}]
8585
>,
86+
InterfaceMethod<
87+
/*desc=*/[{
88+
Like `getShape`, but only returns statically-known information, without
89+
generating any new IR. For each shape dimension, returns >=0 if that
90+
dimension is statically known, or ShapedType::kDynamic otherwise.
91+
}],
92+
/*retTy=*/"SmallVector<int64_t>",
93+
/*methodName=*/"getStaticShape",
94+
/*args=*/(ins),
95+
/*methodBody=*/"",
96+
/*defaultImplementation=*/[{
97+
SmallVector<int64_t> res;
98+
for (OpOperand &opOperand : this->getOperation()->getOpOperands())
99+
llvm::append_range(res, $_op.getShape(&opOperand));
100+
return res;
101+
}]
102+
>,
86103
InterfaceMethod<
87104
/*desc=*/[{
88105
Hook to provide a custom AffineMap used to construct the
@@ -109,39 +126,23 @@ def IndexingMapOpInterface : OpInterface<"IndexingMapOpInterface"> {
109126
>,
110127
InterfaceMethod<
111128
/*desc=*/[{
112-
Returns the static shape of the underlying operand (note this is
113-
op-specific behavior).
129+
Returns the statically-known loop ranges. Composes
130+
`getShapesToLoopsMap()` with the result of `getStaticShape`.
114131
Returns ShapedType::kDynamic for non-statically-known loop ranges.
132+
This is expected to be called by a valid Linalg op
115133
}],
116-
/*retTy=*/"SmallVector<int64_t>",
117-
/*methodName=*/"getStaticOperandShape",
118-
/*args=*/(ins "OpOperand*":$opOperand),
119-
/*methodBody=*/"",
120-
/*defaultImplementation=*/[{
121-
return SmallVector<int64_t>($_op.getShape(opOperand).begin(), $_op.getShape(opOperand).end());
122-
}]
123-
>,
124-
InterfaceMethod<
125-
/*desc=*/[{
126-
Returns loop ranges by composing `getShapesToLoopsMap()` with the
127-
flattened list of operand shapes.
128-
Returns ShapedType::kDynamic for non-statically-known loop ranges.
129-
}],
130-
/*retTy=*/"SmallVector<int64_t>",
134+
/*retTy=*/"SmallVector<int64_t, 4>",
131135
/*methodName=*/"getStaticLoopRanges",
132136
/*args=*/(ins),
133137
/*methodBody=*/"",
134138
/*defaultImplementation=*/[{
135-
SmallVector<int64_t> allShapesSizes;
136-
for (OpOperand &opOperand : this->getOperation()->getOpOperands())
137-
llvm::append_range(allShapesSizes, $_op.getShape(&opOperand));
139+
SmallVector<int64_t> viewSizes = $_op.getStaticShape();
138140
AffineMap invertedMap = $_op.getShapesToLoopsMap();
139-
assert(invertedMap && "expected a valid op");
140-
return invertedMap.compose(allShapesSizes);
141+
assert(invertedMap && "expected a valid Linalg op to call the method");
142+
return invertedMap.compose(viewSizes);
141143
}]
142-
>
144+
>,
143145
];
144-
let verify = [{ return detail::verifyIndexingMapOpInterface($_op); }];
145146
}
146147

147148
#endif // MLIR_INTERFACES_INDEXING_MAP_OP_INTERFACE

mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,67 @@ LogicalResult mlir::linalg::detail::verifyStructuredOpInterface(Operation *op) {
12541254
if (!linalgOp.getShapesToLoopsMap())
12551255
return op->emitOpError("expected the shape-to-loops map to be non-null");
12561256

1257+
// Check if given shapes match to inferred shapes.
1258+
SmallVector<int64_t, 4> endLoopRangeValues = linalgOp.getStaticLoopRanges();
1259+
SmallVector<int64_t, 4> startLoopRangeValues(endLoopRangeValues.size(), 0);
1260+
// Verify only static cases since we can't get exact dimension sizes and
1261+
// loop ranges for dynamic cases in this stage.
1262+
if (llvm::none_of(endLoopRangeValues, ShapedType::isDynamic)) {
1263+
for (int64_t &range : endLoopRangeValues)
1264+
range -= 1;
1265+
for (OpOperand &opOperand : linalgOp->getOpOperands()) {
1266+
AffineMap indexingMap = linalgOp.getMatchingIndexingMap(&opOperand);
1267+
SmallVector<int64_t, 4> startIndices =
1268+
indexingMap.compose(startLoopRangeValues);
1269+
SmallVector<int64_t, 4> endIndices =
1270+
indexingMap.compose(endLoopRangeValues);
1271+
ArrayRef<int64_t> shape = linalgOp.getShape(&opOperand);
1272+
for (auto dim : llvm::seq<int64_t>(0, shape.size())) {
1273+
// Ignore dynamic dimension or the case that the dimension size is 0
1274+
if (ShapedType::isDynamic(shape[dim]) || shape[dim] == 0)
1275+
continue;
1276+
1277+
// The first index or last index should be the maximum or the minimum in
1278+
// the inferred index ranges since the range is increasing or
1279+
// decreasing. The size of dimensions of input/output operands and the
1280+
// maximum value + 1 in the inferred range should be the same. But, for
1281+
// now we check if the inferred ranges are in boundary of input/output
1282+
// operands' size or not in case that Affine Expressions are complicated
1283+
// such as d0 * 3
1284+
// + d1 since it is not easy to handle the issues.
1285+
// Found the case that this solution can't check, for example, (d0, d1)
1286+
// -> (d1 - d0)
1287+
int64_t inferredDimSize =
1288+
std::max(startIndices[dim], endIndices[dim]) + 1;
1289+
if (std::min(startIndices[dim], endIndices[dim]) < 0) {
1290+
std::string mapStr;
1291+
{
1292+
llvm::raw_string_ostream os(mapStr);
1293+
os << indexingMap;
1294+
}
1295+
return op->emitOpError(
1296+
"unexpected result less than 0 at expression #")
1297+
<< dim << " in " << mapStr;
1298+
}
1299+
if (isa<AffineDimExpr>(indexingMap.getResult(dim))) {
1300+
if (inferredDimSize != shape[dim]) {
1301+
return op->emitOpError("inferred input/output operand #")
1302+
<< opOperand.getOperandNumber() << " has shape's dimension #"
1303+
<< dim << " to be " << inferredDimSize << ", but found "
1304+
<< shape[dim];
1305+
}
1306+
} else {
1307+
if (inferredDimSize > shape[dim]) {
1308+
return op->emitOpError("inferred input/output operand #")
1309+
<< opOperand.getOperandNumber() << " has shape's dimension #"
1310+
<< dim << " to be greater than or equal to "
1311+
<< inferredDimSize << ", but found " << shape[dim];
1312+
}
1313+
}
1314+
}
1315+
}
1316+
}
1317+
12571318
// Check the region has exactly one block.
12581319
if (linalgOp->getNumRegions() != 1 ||
12591320
!llvm::hasSingleElement(linalgOp->getRegion(0)))

mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,7 @@ linalg::dropUnitDims(RewriterBase &rewriter, GenericOp genericOp,
398398
return rewriter.notifyMatchFailure(genericOp,
399399
"invalid indexing maps for operation");
400400
}
401-
402-
SmallVector<int64_t> allShapesSizes;
403-
for (OpOperand &opOperand : genericOp->getOpOperands())
404-
llvm::append_range(allShapesSizes, genericOp.getShape(&opOperand));
401+
SmallVector<int64_t> dims = genericOp.getStaticShape();
405402

406403
// 1a. Get the allowed list of dimensions to drop from the `options`.
407404
SmallVector<unsigned> allowedUnitDims = options.controlFn(genericOp);
@@ -414,7 +411,7 @@ linalg::dropUnitDims(RewriterBase &rewriter, GenericOp genericOp,
414411
llvm::SmallDenseSet<unsigned> unitDims;
415412
for (const auto &expr : enumerate(invertedMap.getResults())) {
416413
if (AffineDimExpr dimExpr = dyn_cast<AffineDimExpr>(expr.value())) {
417-
if (allShapesSizes[dimExpr.getPosition()] == 1 &&
414+
if (dims[dimExpr.getPosition()] == 1 &&
418415
unitDimsFilter.count(expr.index()))
419416
unitDims.insert(expr.index());
420417
}

mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "mlir/IR/BuiltinTypes.h"
3232
#include "mlir/IR/OpDefinition.h"
3333
#include "mlir/IR/PatternMatch.h"
34-
#include "mlir/IR/Value.h"
3534
#include "mlir/Support/LLVM.h"
3635
#include "mlir/Transforms/RegionUtils.h"
3736
#include "llvm/ADT/STLExtras.h"
@@ -2218,9 +2217,7 @@ static LogicalResult vectorizeLinalgOpPrecondition(
22182217
LinalgOp linalgOp, ArrayRef<int64_t> inputVectorSizes,
22192218
bool vectorizeNDExtract, bool flatten1DDepthwiseConv) {
22202219
// tensor with dimension of 0 cannot be vectorized.
2221-
if (llvm::any_of(linalgOp->getOpOperands(), [&](OpOperand &operand) {
2222-
return llvm::is_contained(linalgOp.getShape(&operand), 0);
2223-
}))
2220+
if (llvm::is_contained(linalgOp.getStaticShape(), 0))
22242221
return failure();
22252222
// Check API contract for input vector sizes.
22262223
if (!inputVectorSizes.empty() &&

mlir/lib/Interfaces/IndexingMapOpInterface.cpp

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -13,71 +13,3 @@ using namespace mlir;
1313
namespace mlir {
1414
#include "mlir/Interfaces/IndexingMapOpInterface.cpp.inc"
1515
} // namespace mlir
16-
17-
LogicalResult mlir::detail::verifyIndexingMapOpInterface(Operation *op) {
18-
auto imOp = cast<IndexingMapOpInterface>(op);
19-
20-
// Check if given shapes match to inferred shapes.
21-
SmallVector<int64_t, 4> endLoopRangeValues = imOp.getStaticLoopRanges();
22-
SmallVector<int64_t, 4> startLoopRangeValues(endLoopRangeValues.size(), 0);
23-
// Verify only static cases since we can't get exact dimension sizes and
24-
// loop ranges for dynamic cases in this stage.
25-
if (llvm::none_of(endLoopRangeValues, ShapedType::isDynamic)) {
26-
// Exclusive end range.
27-
for (int64_t &range : endLoopRangeValues)
28-
range -= 1;
29-
for (OpOperand &opOperand : imOp->getOpOperands()) {
30-
AffineMap indexingMap = imOp.getMatchingIndexingMap(&opOperand);
31-
SmallVector<int64_t, 4> startIndices =
32-
indexingMap.compose(startLoopRangeValues);
33-
SmallVector<int64_t, 4> endIndices =
34-
indexingMap.compose(endLoopRangeValues);
35-
SmallVector<int64_t> shape = imOp.getStaticOperandShape(&opOperand);
36-
for (auto dim : llvm::seq<int64_t>(0, shape.size())) {
37-
// Ignore dynamic dimension or the case that the dimension size is 0
38-
if (ShapedType::isDynamic(shape[dim]) || shape[dim] == 0)
39-
continue;
40-
41-
// The first index or last index should be the maximum or the minimum in
42-
// the inferred index ranges since the range is increasing or
43-
// decreasing. The size of dimensions of input/output operands and the
44-
// maximum value + 1 in the inferred range should be the same. But, for
45-
// now we check if the inferred ranges are in boundary of input/output
46-
// operands' size or not in case that Affine Expressions are complicated
47-
// such as d0 * 3
48-
// + d1 since it is not easy to handle the issues.
49-
// Found the case that this solution can't check, for example, (d0, d1)
50-
// -> (d1 - d0)
51-
int64_t inferredDimSize =
52-
std::max(startIndices[dim], endIndices[dim]) + 1;
53-
if (std::min(startIndices[dim], endIndices[dim]) < 0) {
54-
std::string mapStr;
55-
{
56-
llvm::raw_string_ostream os(mapStr);
57-
os << indexingMap;
58-
}
59-
return op->emitOpError(
60-
"unexpected result less than 0 at expression #")
61-
<< dim << " in " << mapStr;
62-
}
63-
if (isa<AffineDimExpr>(indexingMap.getResult(dim))) {
64-
if (inferredDimSize != shape[dim]) {
65-
return op->emitOpError("inferred input/output operand #")
66-
<< opOperand.getOperandNumber() << " has shape's dimension #"
67-
<< dim << " to be " << inferredDimSize << ", but found "
68-
<< shape[dim];
69-
}
70-
} else {
71-
if (inferredDimSize > shape[dim]) {
72-
return op->emitOpError("inferred input/output operand #")
73-
<< opOperand.getOperandNumber() << " has shape's dimension #"
74-
<< dim << " to be greater than or equal to "
75-
<< inferredDimSize << ", but found " << shape[dim];
76-
}
77-
}
78-
}
79-
}
80-
}
81-
82-
return success();
83-
}

0 commit comments

Comments
 (0)