summaryrefslogtreecommitdiff
path: root/mlir/lib/Interfaces/InferTypeOpInterface.cpp
AgeCommit message (Collapse)Author
2025-11-10[mlir][Interfaces] Add interface methods to allow reifying single ↵MaheshRavishankar
result/single dim of result. (#162924) Current implementation of `reifyResultShapes` forces all implementations to return all dimensions of all results. This can be wasteful when you only require dimensions of one result, or a single dimension of a result. Further this also creates issues with using patterns to resolve the `tensor.dim` and `memref.dim` operations since the extra operations created result in the pattern rewriter entering an infinite loop (eventually breaking out of the loop due to the iteration limit on the pattern rewriter). This is demonstrated by some of the test cases added here that hit this limit when using `--resolve-shaped-type-result-dims` and `--resolve-ranked-shaped-type-result-dims`. To resolve this issue the interface should allow for creating just the operations needed. This change is the first step in resolving this. The original implementation was done with the restriction in mind that it might not always be possible to compute dimension of a single result or one dimension of a single result in all cases. To account for such cases, two additional interface methods are added - `reifyShapeOfResult` (which allows reifying dimensions of just one result), has a default implementation that calls `reifyResultShapes` and returns the dimensions of a single result. - `reifyDimOfResult` (which allows reifying a single dimension of a single result) has a default implementation that calls `reifyDimOfResult` and returns the value for the dimension of the result (which in turn for the default case would call `reifyDimOfResult`). While this change sets up the interface, ideally most operations will implement the `refiyDimOfResult` when possible. For almost all operations in tree this is true. Subsequent commits will change those incrementally. Some of the tests added here that check that the default implementations for the above method work as expected, also end up hitting the pattern rewriter limit when using `--resolve-ranked-shaped-type-result-dims`/ `--resolve-ranked-shaped-type-result-dims`. For testing purposes, a flag is added to these passes that ignore the error returned by the pattern application (this flag is left on by default to maintain current state). Changes required downstream to integrate this change 1. In operation definitions in .td files, for those operations that implement the `ReifyRankedShapedTypeOpInterface`. ``` def <op-name> : Op<..., [..., DeclareOpInterfaceMethods[ReifyRankedShapedTypeOpInterface]]> ``` should be changed to ``` def <op-name> : Op<..., [..., DeclareOpInterfaceMethods[ReifyRankedShapedTypeOpInterface, [ "reifyResultShapes"]]]> ``` --------- Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
2025-04-19[mlir] Clean up prints with `llvm::interleaved`. NFC. (#136468)Jakub Kuderski
2025-01-27[mlir][Tensor] Rework `ReifyRankedShapedTypeInterface` implementation for ↵MaheshRavishankar
`tensor.expand_shape` op. (#113501) The op carries the output-shape directly. This can be used directly. Also adds a method to get the shape as a `SmallVector<OpFoldResult>`. Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
2024-12-21[Interfaces] Migrate away from PointerUnion::{is,get} (NFC) (#120845)Kazu Hirata
Note that PointerUnion::{is,get} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> I'm not touching PointerUnion::dyn_cast for now because it's a bit complicated; we could blindly migrate it to dyn_cast_if_present, but we should probably use dyn_cast when the operand is known to be non-null.
2024-10-16[mlir][IR] Improve error message when return type could not be inferred ↵Matthias Springer
(#112336) Print an error such as the following one before terminating program execution. ``` mlir/test/Dialect/SparseTensor/convert_dense2sparse.mlir:26:8: remark: location of op %0 = sparse_tensor.convert %arg0 : tensor<?xi32> to tensor<?xi32, #SparseVector> ^ LLVM ERROR: Failed to infer result type(s): "sparse_tensor.positions"(...) {} : (index) -> ( ??? ) (stack trace follows) ```
2024-01-04[mlir] add a way to query non-property attributes (#76959)Oleksandr "Alex" Zinenko
This helps support generic manipulation of operations that don't (yet) use properties to store inherent attributes. Use this mechanism in type inference and operation equivalence. Note that only minimal unit tests are introduced as all the upstream dialects seem to have been updated to use properties and the non-property behavior is essentially deprecated and untested.
2024-01-03[mlir] update InferTypeOpInterface after c1eab57673ef3eAlex Zinenko
The change in c1eab57673ef3eb2842c0fbe454d7878854cf54c fixed the behavior of `getDiscardableAttrDictionary` for ops that are not using properties to only return discardable attributes. `InferTypeOpInterface` was relying on the wrong behavior when constructing an adaptor and would assume that all attributes were discardable, which is not the case.
2023-07-12[ODS] Extra Concrete Declarations and Definitions under TraitsAmanda Tang
Support extra concrete class declarations and definitions under NativeTrait that get injected into the class that specifies the trait. Extra declarations and definitions can be passed in as template arguments for NativeOpTraitNativeAttrTrait and NativeTypeTrait. Usage examples of this feature include: - Creating a wrapper Trait for authoring inferReturnTypes with the OpAdaptor by specifying necessary Op specific declarations and definitions directly in the trait - Refactoring the InferTensorType trait Reviewed By: jpienaar Differential Revision: https://reviews.llvm.org/D154731
2023-05-26[mlir] Move casting calls from methods to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Context: - https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" - Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This patch updates all remaining uses of the deprecated functionality in mlir/. This was done with clang-tidy as described below and further modifications to GPUBase.td and OpenMPOpsInterfaces.td. Steps are described per line, as comments are removed by git: 0. Retrieve the change from the following to build clang-tidy with an additional check: main...tpopp:llvm-project:tidy-cast-check 1. Build clang-tidy 2. Run clang-tidy over your entire codebase while disabling all checks and enabling the one relevant one. Run on all header files also. 3. Delete .inc files that were also modified, so the next build rebuilds them to a pure state. ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -header-filter=mlir/ mlir/* -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc ``` Differential Revision: https://reviews.llvm.org/D151542
2023-05-15Cleanup uses of getAttrDictionary() in MLIR to use ↵Mehdi Amini
getDiscardableAttrDictionary() when possible This also speeds up some benchmarks in compiling simple fortan file by 2x! Fixes #62687 Differential Revision: https://reviews.llvm.org/D150540
2023-05-12[mlir] Move casting calls from methods to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Caveats include: - This clang-tidy script probably has more problems. - This only touches C++ code, so nothing that is being generated. Context: - https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" - Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This first patch was created with the following steps. The intention is to only do automated changes at first, so I waste less time if it's reverted, and so the first mass change is more clear as an example to other teams that will need to follow similar steps. Steps are described per line, as comments are removed by git: 0. Retrieve the change from the following to build clang-tidy with an additional check: https://github.com/llvm/llvm-project/compare/main...tpopp:llvm-project:tidy-cast-check 1. Build clang-tidy 2. Run clang-tidy over your entire codebase while disabling all checks and enabling the one relevant one. Run on all header files also. 3. Delete .inc files that were also modified, so the next build rebuilds them to a pure state. 4. Some changes have been deleted for the following reasons: - Some files had a variable also named cast - Some files had not included a header file that defines the cast functions - Some files are definitions of the classes that have the casting methods, so the code still refers to the method instead of the function without adding a prefix or removing the method declaration at the same time. ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -header-filter=mlir/ mlir/* -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc git restore mlir/lib/IR mlir/lib/Dialect/DLTI/DLTI.cpp\ mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp\ mlir/lib/**/IR/\ mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp\ mlir/lib/Dialect/Vector/Transforms/LowerVectorMultiReduction.cpp\ mlir/test/lib/Dialect/Test/TestTypes.cpp\ mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp\ mlir/test/lib/Dialect/Test/TestAttributes.cpp\ mlir/unittests/TableGen/EnumsGenTest.cpp\ mlir/test/python/lib/PythonTestCAPI.cpp\ mlir/include/mlir/IR/ ``` Differential Revision: https://reviews.llvm.org/D150123
2023-05-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-05-01Revert "Introduce MLIR Op Properties"Mehdi Amini
This reverts commit d572cd1b067f1177a981a4711bf2e501eaa8117b. Some bots are broken and investigation is needed before relanding.
2023-05-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Differential Revision: https://reviews.llvm.org/D141742
2023-03-10[mlir][NFC] reifyResultShapes: Add extra error checkingMatthias Springer
This change adds a new helper function `mlir::reifyResultShapes` that calls the corresponding interface method and also checks the result produced by the implementation when running in debug mode. Bugs due to incorrect interface implementations can be difficult to debug. This helper function also reduces the amount of code needed at call sites: the cast to `ReifyRankedShapedTypeOpInterface` is done in the helper function. Differential Revision: https://reviews.llvm.org/D145777
2022-12-28Apply clang-tidy fixes for readability-identifier-naming in ↵Mehdi Amini
InferTypeOpInterface.cpp (NFC)
2022-12-17mlir/tblgen: use std::optional in generationRamkumar Ramachandra
This is part of an effort to migrate from llvm::Optional to std::optional. This patch changes the way mlir-tblgen generates .inc files, and modifies tests and documentation appropriately. It is a "no compromises" patch, and doesn't leave the user with an unpleasant mix of llvm::Optional and std::optional. A non-trivial change has been made to ControlFlowInterfaces to split one constructor into two, relating to a build failure on Windows. See also: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716 Signed-off-by: Ramkumar Ramachandra <r@artagnon.com> Differential Revision: https://reviews.llvm.org/D138934
2022-12-07[MLIR] Allow ShapedTypeComponents with attribute in inferReturnTensorTypessmit-hinsu
Originally, inferReturnTensorTypes didn't support shaped type components containing an attribute just because there wasn't any motivating use-case. Removing that limitation and using it to set the encoding attribute for RankedTensorType. Updated the existing test to set result attribute based on the first operand, if available. Signed-off-by: Smit Hinsu <smittvhinsu@gmail.com> Differential Revision: https://reviews.llvm.org/D139271
2022-07-23Use callables directly in any_of, count_if, etc (NFC)Kazu Hirata
2022-07-18[mlir] Add refineReturnTypes to InferTypeOpInterfaceJacques Pienaar
refineReturnType method shares the same parameters as inferReturnTypes but gets passed in the return types of the op if known that can be used during refinement passes or for more op specific error reporting. Currently the error reporting on failure is generic and doesn't allow for specializing the returned result based on failure, with this change what would previously have been a separate trait with specialized verification can just be handled as part of inferrence rather than duplicated. refineReturnTypes behaves like inferReturnTypes if no result types are fed in, while the current verification is recast as the default implementation for refineReturnTypes with it calling inferReturnTypes (and so the default type verification now goes through refine and allows for more op specific inference mismatch errors). Differential Revision: https://reviews.llvm.org/D129955
2022-04-14[mlir] Add assert to fail with more info (NFC)Jacques Pienaar
This would have assert before during tensor type construction with opaque error, assert and fail earlier now.
2022-01-02Apply clang-tidy fixes for performance-for-range-copy to MLIR (NFC)Mehdi Amini
2021-11-09[mlir] Refactor ElementsAttr's value access APIRiver Riddle
There are several aspects of the API that either aren't easy to use, or are deceptively easy to do the wrong thing. The main change of this commit is to remove all of the `getValue<T>`/`getFlatValue<T>` from ElementsAttr and instead provide operator[] methods on the ranges returned by `getValues<T>`. This provides a much more convenient API for the value ranges. It also removes the easy-to-be-inefficient nature of getValue/getFlatValue, which under the hood would construct a new range for the type `T`. Constructing a range is not necessarily cheap in all cases, and could lead to very poor performance if used within a loop; i.e. if you were to naively write something like: ``` DenseElementsAttr attr = ...; for (int i = 0; i < size; ++i) { // We are internally rebuilding the APFloat value range on each iteration!! APFloat it = attr.getFlatValue<APFloat>(i); } ``` Differential Revision: https://reviews.llvm.org/D113229
2021-09-21[mlir] Add value_begin/value_end methods to DenseElementsAttrRiver Riddle
Currently DenseElementsAttr only exposes the ability to get the full range of values for a given type T, but there are many situations where we just want the beginning/end iterator. This revision adds proper value_begin/value_end methods for all of the supported T types, and also cleans up a bit of the interface. Differential Revision: https://reviews.llvm.org/D104173
2021-08-10[mlir] Enable specifying querying function in ValueShapeRangeJacques Pienaar
This enables querying shapes/values as shapes without mutating the IR directly (e.g., towards enabling doing inference in analysis & application steps, inferring function shape with constant from callsite, ...). Add a new ShapeAdaptor that abstracts over whether shape is from Type or ShapedTypeComponents or DenseIntElementsAttribute. This adds new accessors to ValueShapeRange to get Shape and value as shape, but doesn't restrict or remove the previous way of accessing Type via the Value for now, that does mean a less refined shape could be accidentally queried and will be restricted in follow up. Currently restricted Value query to what can be represented as Shape. So only supports cases where constant subgraph evaluation's output is a shape. I had considered making it more general, but without TBD extern attribute concept or some such a user cannot today uniformly avoid overhead. Update TOSA ops and also the shape inference pass. Differential Revision: https://reviews.llvm.org/D107768
2021-07-22[mlir] Also update inferReturnTensorTypes (NFC)Jacques Pienaar
Missed this one in the first go.
2021-03-29[mlir] Enhance InferShapedTypeOpInterface and move LinalgOps to use them.MaheshRavishankar
A new `InterfaceMethod` is added to `InferShapedTypeOpInterface` that allows an operation to return the `Value`s for each dim of its results. It is intended for the case where the `Value` returned for each dim is computed using the operands and operation attributes. This interface method is for cases where the result dim of an operation can be computed independently, and it avoids the need to aggregate all dims of a result into a single shape value. This also implies that this is not suitable for cases where the result type is unranked (for which the existing interface methods is to be used). Also added is a canonicalization pattern that uses this interface and resolves the shapes of the output in terms of the shapes of the inputs. Moving Linalg ops to use this interface, so that many canonicalization patterns implemented for individual linalg ops to achieve the same result can be removed in favor of the added canonicalization pattern. Differential Revision: https://reviews.llvm.org/D97887
2021-02-02[mlir] Print more verbose message in case of type inference errorVladislav Vinogradov
Include the types into the error message. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D95854
2020-12-03[mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.hRiver Riddle
This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references. Differential Revision: https://reviews.llvm.org/D92435
2020-05-07[mlir] Add NamedAttrListJacques Pienaar
This is a wrapper around vector of NamedAttributes that keeps track of whether sorted and does some minimal effort to remain sorted (doing more, e.g., appending attributes in sorted order, could be done in follow up). It contains whether sorted and if a DictionaryAttr is queried, it caches the returned DictionaryAttr along with whether sorted. Change MutableDictionaryAttr to always return a non-null Attribute even when empty (reserve null cases for errors). To this end change the getter to take a context as input so that the empty DictionaryAttr could be queried. Also create one instance of the empty dictionary attribute that could be reused without needing to lock context etc. Update infer type op interface to use DictionaryAttr and use NamedAttrList to avoid incurring multiple conversion costs. Fix bug in sorting helper function. Differential Revision: https://reviews.llvm.org/D79463
2020-03-10[mlir][NFC] Move the operation interfaces out of Analysis/ and into a new ↵River Riddle
Interfaces/ directory. The interfaces themselves aren't really analyses, they may be used by analyses though. Having them in Analysis can also create cyclic dependencies if an analysis depends on a specific dialect, that also provides one of the interfaces. Differential Revision: https://reviews.llvm.org/D75867