/*===- 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 (*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 (*getStaticOperandShape)(const Concept *impl, ::mlir::Operation *, OpOperand*); SmallVector (*getStaticLoopRanges)(const Concept *impl, ::mlir::Operation *); }; template 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 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 getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand); static inline SmallVector getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); }; template 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 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 getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand); static inline SmallVector getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); }; template class ExternalModel : public FallbackModel { public: using ConcreteEntity = ConcreteOp; SmallVector 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 getStaticOperandShape(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const; SmallVector getStaticLoopRanges(::mlir::Operation *tablegen_opaque_val) const; }; }; template struct IndexingMapOpInterfaceTrait; } // namespace detail class IndexingMapOpInterface : public ::mlir::OpInterface { public: using ::mlir::OpInterface::OpInterface; template struct Trait : public detail::IndexingMapOpInterfaceTrait {}; /// Return the indexing maps attribute within the current operation. ArrayAttr getIndexingMaps(); /// Return the indexing maps within the current operation. SmallVector 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 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 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 struct IndexingMapOpInterfaceTrait : public ::mlir::OpInterface::Trait { /// Return the indexing maps within the current operation. SmallVector getIndexingMapsArray() { auto range = (*static_cast(this)).getIndexingMaps() .template getAsValueRange(); 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(this)).getIndexingMaps().template getAsValueRange(); 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(this)).getIndexingMapsArray(); return concatAffineMaps(maps, (*static_cast(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(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 getStaticOperandShape(OpOperand* opOperand) { SmallVector res; llvm::append_range(res, (*static_cast(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 getStaticLoopRanges() { SmallVector allShapesSizes; for (OpOperand &opOperand : this->getOperation()->getOpOperands()) llvm::append_range(allShapesSizes, (*static_cast(this)).getShape(&opOperand)); AffineMap invertedMap = (*static_cast(this)).getShapesToLoopsMap(); assert(invertedMap && "expected a valid op"); return invertedMap.compose(allShapesSizes); } }; } // namespace mlir::detail namespace mlir { template ArrayAttr detail::IndexingMapOpInterfaceInterfaceTraits::Model::getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getIndexingMaps(); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::Model::getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getIndexingMapsArray(); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model::getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) { return (llvm::cast(tablegen_opaque_val)).getMatchingIndexingMap(opOperand); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model::getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getLoopsToShapesMap(); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::Model::getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getShapesToLoopsMap(); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::Model::getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) { return (llvm::cast(tablegen_opaque_val)).getStaticOperandShape(opOperand); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::Model::getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getStaticLoopRanges(); } template ArrayAttr detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getIndexingMaps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getIndexingMaps(tablegen_opaque_val); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getIndexingMapsArray(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getIndexingMapsArray(tablegen_opaque_val); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getMatchingIndexingMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) { return static_cast(impl)->getMatchingIndexingMap(tablegen_opaque_val, opOperand); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getLoopsToShapesMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getLoopsToShapesMap(tablegen_opaque_val); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getShapesToLoopsMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getShapesToLoopsMap(tablegen_opaque_val); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getStaticOperandShape(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, OpOperand* opOperand) { return static_cast(impl)->getStaticOperandShape(tablegen_opaque_val, opOperand); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::FallbackModel::getStaticLoopRanges(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getStaticLoopRanges(tablegen_opaque_val); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getIndexingMapsArray(::mlir::Operation *tablegen_opaque_val) const { auto range = (llvm::cast(tablegen_opaque_val)).getIndexingMaps() .template getAsValueRange(); return {range.begin(), range.end()}; } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getMatchingIndexingMap(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const { assert(opOperand->getOwner() == this->getOperation()); auto indexingMaps = (llvm::cast(tablegen_opaque_val)).getIndexingMaps().template getAsValueRange(); return *(indexingMaps.begin() + opOperand->getOperandNumber()); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getLoopsToShapesMap(::mlir::Operation *tablegen_opaque_val) const { auto maps = (llvm::cast(tablegen_opaque_val)).getIndexingMapsArray(); return concatAffineMaps(maps, (llvm::cast(tablegen_opaque_val)).getContext()); } template AffineMap detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getShapesToLoopsMap(::mlir::Operation *tablegen_opaque_val) const { return inversePermutation((llvm::cast(tablegen_opaque_val)).getLoopsToShapesMap()); } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getStaticOperandShape(::mlir::Operation *tablegen_opaque_val, OpOperand*opOperand) const { SmallVector res; llvm::append_range(res, (llvm::cast(tablegen_opaque_val)).getShape(opOperand)); return res; } template SmallVector detail::IndexingMapOpInterfaceInterfaceTraits::ExternalModel::getStaticLoopRanges(::mlir::Operation *tablegen_opaque_val) const { SmallVector allShapesSizes; for (OpOperand &opOperand : this->getOperation()->getOpOperands()) llvm::append_range(allShapesSizes, (llvm::cast(tablegen_opaque_val)).getShape(&opOperand)); AffineMap invertedMap = (llvm::cast(tablegen_opaque_val)).getShapesToLoopsMap(); assert(invertedMap && "expected a valid op"); return invertedMap.compose(allShapesSizes); } } // namespace mlir