Files
gps/tools/local/circt/include/mlir/Interfaces/IndexingMapOpInterface.h.inc
T
2026-07-12 11:01:51 +03:00

311 lines
18 KiB
C++

/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|* Interface Declarations *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
namespace mlir {
/// Interface for operations that connect an iteration domain to operands via
/// affine maps. Provides methods to access indexing maps between iteration
/// domain and operand index spaces.
class IndexingMapOpInterface;
} // namespace mlir
namespace mlir {
/// Interface for operations that connect an iteration domain to operands via
/// affine maps. Provides methods to access indexing maps between iteration
/// domain and operand index spaces.
namespace detail {
struct IndexingMapOpInterfaceInterfaceTraits {
struct Concept {
/// The methods defined by the interface.
ArrayAttr (*getIndexingMaps)(const Concept *impl, ::mlir::Operation *);
SmallVector<AffineMap> (*getIndexingMapsArray)(const Concept *impl, ::mlir::Operation *);
AffineMap (*getMatchingIndexingMap)(const Concept *impl, ::mlir::Operation *, OpOperand*);
AffineMap (*getLoopsToShapesMap)(const Concept *impl, ::mlir::Operation *);
AffineMap (*getShapesToLoopsMap)(const Concept *impl, ::mlir::Operation *);
SmallVector<int64_t> (*getStaticOperandShape)(const Concept *impl, ::mlir::Operation *, OpOperand*);
SmallVector<int64_t> (*getStaticLoopRanges)(const Concept *impl, ::mlir::Operation *);
};
template<typename ConcreteOp>
class Model : public Concept {
public:
using Interface = ::mlir::IndexingMapOpInterface;
Model() : Concept{getIndexingMaps, getIndexingMapsArray, getMatchingIndexingMap, getLoopsToShapesMap, getShapesToLoopsMap, getStaticOperandShape, getStaticLoopRanges} {}
static inline ArrayAttr getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline SmallVector<AffineMap> getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline AffineMap getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand);
static inline AffineMap getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline AffineMap getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline SmallVector<int64_t> getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand);
static inline SmallVector<int64_t> getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
};
template<typename ConcreteOp>
class FallbackModel : public Concept {
public:
using Interface = ::mlir::IndexingMapOpInterface;
FallbackModel() : Concept{getIndexingMaps, getIndexingMapsArray, getMatchingIndexingMap, getLoopsToShapesMap, getShapesToLoopsMap, getStaticOperandShape, getStaticLoopRanges} {}
static inline ArrayAttr getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline SmallVector<AffineMap> getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline AffineMap getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand);
static inline AffineMap getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline AffineMap getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline SmallVector<int64_t> getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand);
static inline SmallVector<int64_t> getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
};
template<typename ConcreteModel, typename ConcreteOp>
class ExternalModel : public FallbackModel<ConcreteModel> {
public:
using ConcreteEntity = ConcreteOp;
SmallVector<AffineMap> getIndexingMapsArray(::mlir::Operation *tablegen_opaque_val) const;
AffineMap getMatchingIndexingMap(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const;
AffineMap getLoopsToShapesMap(::mlir::Operation *tablegen_opaque_val) const;
AffineMap getShapesToLoopsMap(::mlir::Operation *tablegen_opaque_val) const;
SmallVector<int64_t> getStaticOperandShape(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const;
SmallVector<int64_t> getStaticLoopRanges(::mlir::Operation *tablegen_opaque_val) const;
};
};
template <typename ConcreteOp>
struct IndexingMapOpInterfaceTrait;
} // namespace detail
class IndexingMapOpInterface : public ::mlir::OpInterface<IndexingMapOpInterface, detail::IndexingMapOpInterfaceInterfaceTraits> {
public:
using ::mlir::OpInterface<IndexingMapOpInterface, detail::IndexingMapOpInterfaceInterfaceTraits>::OpInterface;
template <typename ConcreteOp>
struct Trait : public detail::IndexingMapOpInterfaceTrait<ConcreteOp> {};
/// Return the indexing maps attribute within the current operation.
ArrayAttr getIndexingMaps();
/// Return the indexing maps within the current operation.
SmallVector<AffineMap> getIndexingMapsArray();
/// Return the input or output indexing map for `opOperand`.
AffineMap getMatchingIndexingMap(OpOperand* opOperand);
/// Hook to provide a custom AffineMap used to compute all the operand
/// subshapes given loop bounds. This is used to answer the question: "given
/// an iteration space over the codomain, what are the subshapes of the
/// operands involved in the computation".
/// The default behavior is to just concatenate all the indexing maps.
/// A custom AffineMap allows providing a map that can be used to
/// compute subshapes even in cases where the concatenation of indexing maps
/// (i.e. the data traversal order) is not a simple permutation of the loop
/// traversal order. It is then possible to define ops with skewed data
/// traversal order for which we can still easily compute hyperrectangular
/// loop bounds and subviews.
AffineMap getLoopsToShapesMap();
/// Hook to provide a custom AffineMap used to construct the
/// hyperrectangular loop iteration space given all the operand subshapes.
/// This is used to answer the question:
/// "Given a list of operand ranges, what is the subportion of the iteration
/// space involved in the computation".
/// This is the inverse problem of `getLoopsToShapesMap`.
/// Return the empty AffineMap when such an AffineMap cannot be constructed.
/// The default behavior is based on a very simple inference procedure that
/// only works with permutation affine maps.
/// A more advanced Tensor-Comprehension like inference is possible but has
/// proven to be ambiguous in unfavorable case.
/// A safer and more robust alternative is to allow each op to define
/// its own AffineMap.
AffineMap getShapesToLoopsMap();
/// Returns the static shape of the underlying operand (note this is
/// op-specific behavior).
/// Returns ShapedType::kDynamic for non-statically-known loop ranges.
SmallVector<int64_t> getStaticOperandShape(OpOperand* opOperand);
/// Returns loop ranges by composing `getShapesToLoopsMap()` with the
/// flattened list of operand shapes.
/// Returns ShapedType::kDynamic for non-statically-known loop ranges.
SmallVector<int64_t> getStaticLoopRanges();
// Verifier implementation for IndexingMapOpInterface.
// This must be called manually as part of other verifiers so that the
// verification order, and meaningful error messages, are not preempted.
LogicalResult verifyImpl();
};
} // namespace mlir
namespace mlir::detail {
template <typename ConcreteOp>
struct IndexingMapOpInterfaceTrait : public ::mlir::OpInterface<IndexingMapOpInterface, detail::IndexingMapOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
/// Return the indexing maps within the current operation.
SmallVector<AffineMap> getIndexingMapsArray() {
auto range = (*static_cast<ConcreteOp *>(this)).getIndexingMaps()
.template getAsValueRange<AffineMapAttr>();
return {range.begin(), range.end()};
}
/// Return the input or output indexing map for `opOperand`.
AffineMap getMatchingIndexingMap(OpOperand* opOperand) {
assert(opOperand->getOwner() == this->getOperation());
auto indexingMaps =
(*static_cast<ConcreteOp *>(this)).getIndexingMaps().template getAsValueRange<AffineMapAttr>();
return *(indexingMaps.begin() + opOperand->getOperandNumber());
}
/// Hook to provide a custom AffineMap used to compute all the operand
/// subshapes given loop bounds. This is used to answer the question: "given
/// an iteration space over the codomain, what are the subshapes of the
/// operands involved in the computation".
/// The default behavior is to just concatenate all the indexing maps.
/// A custom AffineMap allows providing a map that can be used to
/// compute subshapes even in cases where the concatenation of indexing maps
/// (i.e. the data traversal order) is not a simple permutation of the loop
/// traversal order. It is then possible to define ops with skewed data
/// traversal order for which we can still easily compute hyperrectangular
/// loop bounds and subviews.
AffineMap getLoopsToShapesMap() {
auto maps = (*static_cast<ConcreteOp *>(this)).getIndexingMapsArray();
return concatAffineMaps(maps, (*static_cast<ConcreteOp *>(this)).getContext());
}
/// Hook to provide a custom AffineMap used to construct the
/// hyperrectangular loop iteration space given all the operand subshapes.
/// This is used to answer the question:
/// "Given a list of operand ranges, what is the subportion of the iteration
/// space involved in the computation".
/// This is the inverse problem of `getLoopsToShapesMap`.
/// Return the empty AffineMap when such an AffineMap cannot be constructed.
/// The default behavior is based on a very simple inference procedure that
/// only works with permutation affine maps.
/// A more advanced Tensor-Comprehension like inference is possible but has
/// proven to be ambiguous in unfavorable case.
/// A safer and more robust alternative is to allow each op to define
/// its own AffineMap.
AffineMap getShapesToLoopsMap() {
return inversePermutation((*static_cast<ConcreteOp *>(this)).getLoopsToShapesMap());
}
/// Returns the static shape of the underlying operand (note this is
/// op-specific behavior).
/// Returns ShapedType::kDynamic for non-statically-known loop ranges.
SmallVector<int64_t> getStaticOperandShape(OpOperand* opOperand) {
SmallVector<int64_t> res;
llvm::append_range(res, (*static_cast<ConcreteOp *>(this)).getShape(opOperand));
return res;
}
/// Returns loop ranges by composing `getShapesToLoopsMap()` with the
/// flattened list of operand shapes.
/// Returns ShapedType::kDynamic for non-statically-known loop ranges.
SmallVector<int64_t> getStaticLoopRanges() {
SmallVector<int64_t> allShapesSizes;
for (OpOperand &opOperand : this->getOperation()->getOpOperands())
llvm::append_range(allShapesSizes, (*static_cast<ConcreteOp *>(this)).getShape(&opOperand));
AffineMap invertedMap = (*static_cast<ConcreteOp *>(this)).getShapesToLoopsMap();
assert(invertedMap && "expected a valid op");
return invertedMap.compose(allShapesSizes);
}
};
} // namespace mlir::detail
namespace mlir {
template<typename ConcreteOp>
ArrayAttr detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndexingMaps();
}
template<typename ConcreteOp>
SmallVector<AffineMap> detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndexingMapsArray();
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getMatchingIndexingMap(opOperand);
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopsToShapesMap();
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getShapesToLoopsMap();
}
template<typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getStaticOperandShape(opOperand);
}
template<typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::Model<ConcreteOp>::getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getStaticLoopRanges();
}
template<typename ConcreteOp>
ArrayAttr detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getIndexingMaps(tablegen_opaque_val);
}
template<typename ConcreteOp>
SmallVector<AffineMap> detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getIndexingMapsArray(tablegen_opaque_val);
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) {
return static_cast<const ConcreteOp *>(impl)->getMatchingIndexingMap(tablegen_opaque_val, opOperand);
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopsToShapesMap(tablegen_opaque_val);
}
template<typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getShapesToLoopsMap(tablegen_opaque_val);
}
template<typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) {
return static_cast<const ConcreteOp *>(impl)->getStaticOperandShape(tablegen_opaque_val, opOperand);
}
template<typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getStaticLoopRanges(tablegen_opaque_val);
}
template<typename ConcreteModel, typename ConcreteOp>
SmallVector<AffineMap> detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getIndexingMapsArray(::mlir::Operation *tablegen_opaque_val) const {
auto range = (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndexingMaps()
.template getAsValueRange<AffineMapAttr>();
return {range.begin(), range.end()};
}
template<typename ConcreteModel, typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getMatchingIndexingMap(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const {
assert(opOperand->getOwner() == this->getOperation());
auto indexingMaps =
(llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndexingMaps().template getAsValueRange<AffineMapAttr>();
return *(indexingMaps.begin() + opOperand->getOperandNumber());
}
template<typename ConcreteModel, typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopsToShapesMap(::mlir::Operation *tablegen_opaque_val) const {
auto maps = (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getIndexingMapsArray();
return concatAffineMaps(maps, (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getContext());
}
template<typename ConcreteModel, typename ConcreteOp>
AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getShapesToLoopsMap(::mlir::Operation *tablegen_opaque_val) const {
return inversePermutation((llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopsToShapesMap());
}
template<typename ConcreteModel, typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getStaticOperandShape(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const {
SmallVector<int64_t> res;
llvm::append_range(res, (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getShape(opOperand));
return res;
}
template<typename ConcreteModel, typename ConcreteOp>
SmallVector<int64_t> detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getStaticLoopRanges(::mlir::Operation *tablegen_opaque_val) const {
SmallVector<int64_t> allShapesSizes;
for (OpOperand &opOperand : this->getOperation()->getOpOperands())
llvm::append_range(allShapesSizes, (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getShape(&opOperand));
AffineMap invertedMap = (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getShapesToLoopsMap();
assert(invertedMap && "expected a valid op");
return invertedMap.compose(allShapesSizes);
}
} // namespace mlir