14 #include "mlir/Interfaces/IndexingMapOpInterface.cpp.inc"
17 LogicalResult mlir::IndexingMapOpInterface::verifyImpl() {
19 if (
static_cast<int64_t
>(getIndexingMapsArray().size()) !=
20 getOperation()->getNumOperands())
21 return this->emitOpError(
"expected the number of indexing_map (")
22 << getIndexingMapsArray().size()
23 <<
") to be equal to the number of input/output operands ("
24 << getOperation()->getNumOperands() <<
")";
26 AffineMap invertedMap = getShapesToLoopsMap();
29 llvm::raw_string_ostream os(str);
30 getLoopsToShapesMap().print(os);
31 return this->emitOpError(
"invalid indexing maps are non-invertible: ")
39 for (
OpOperand &opOperand : getOperation()->getOpOperands()) {
40 AffineMap indexingMap = getMatchingIndexingMap(&opOperand);
44 return getOperation()->emitOpError(
"unexpected symbols in indexing_map #")
45 << opOperand.getOperandNumber();
48 if (indexingMap.
getNumDims() != endLoopRangeValues.size())
49 return getOperation()->emitOpError(
"expected indexing_map #")
50 << opOperand.getOperandNumber() <<
" to have "
51 << endLoopRangeValues.size()
52 <<
" dim(s) to match the number of loops";
55 int64_t rank = shape.size();
58 return getOperation()->emitOpError(
"expected operand rank (")
59 << rank <<
") to match the result rank of indexing_map #"
60 << opOperand.getOperandNumber() <<
" ("
68 if (llvm::none_of(endLoopRangeValues, ShapedType::isDynamic)) {
70 for (int64_t &range : endLoopRangeValues)
72 for (
OpOperand &opOperand : getOperation()->getOpOperands()) {
73 AffineMap indexingMap = getMatchingIndexingMap(&opOperand);
75 indexingMap.
compose(startLoopRangeValues);
78 for (
auto dim : llvm::seq<int64_t>(0, shape.size())) {
80 if (ShapedType::isDynamic(shape[dim]) || shape[dim] == 0)
93 int64_t inferredDimSize =
94 std::max(startIndices[dim], endIndices[dim]) + 1;
95 if (
std::min(startIndices[dim], endIndices[dim]) < 0) {
98 llvm::raw_string_ostream os(mapStr);
101 return this->emitOpError(
102 "unexpected result less than 0 at expression #")
103 << dim <<
" in " << mapStr;
105 if (isa<AffineDimExpr>(indexingMap.
getResult(dim))) {
106 if (inferredDimSize != shape[dim]) {
107 return this->emitOpError(
"inferred input/output operand #")
108 << opOperand.getOperandNumber() <<
" has shape's dimension #"
109 << dim <<
" to be " << inferredDimSize <<
", but found "
113 if (inferredDimSize > shape[dim]) {
114 return this->emitOpError(
"inferred input/output operand #")
115 << opOperand.getOperandNumber() <<
" has shape's dimension #"
116 << dim <<
" to be greater than or equal to "
117 << inferredDimSize <<
", but found " << shape[dim];
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
unsigned getNumSymbols() const
unsigned getNumDims() const
unsigned getNumResults() const
AffineExpr getResult(unsigned idx) const
AffineMap compose(AffineMap map) const
Returns the AffineMap resulting from composing this with map.
This class represents an operand of an operation.
Include the generated interface declarations.