Original interfaces are not safe to be called during dialect conversion.
This is because some ops (e.g. dynamic_reshape(input, target_shape))
depend on the values of their operands to calculate the output shape.
However the operands may be out of reach during dialect conversion (e.g.
converting from tensor world to buffer world). This patch provides a new
kind of interface which accpets user-provided operands to solve this
problem.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I am +1 on the direction here.
mlir/include/mlir/Interfaces/InferTypeOpInterface.td | ||
---|---|---|
159 | Do we really need two versions of this function here? I'd prefer to only have the variant with explicit operands at the interface level. What is now a default implementation of the existing interface could instead be just a helper/wrapper that can be used when the operands are the actual operands. This has the disadvantage that we would need to refactor all implementations and users of this interface. Longer term, it has the big advantage that the interfaces cannot go out of sync. |
mlir/include/mlir/Interfaces/InferTypeOpInterface.td | ||
---|---|---|
159 | Thanks! I agree it's better to have one version in the long term. One quick question is: Where to put these helper/wrapper function? It seems more convenient if they are in the interface class (thus all subclasses no need to do wrapper again). I don't know if it's possible to implement something like non override method inside a OpInterface? Or we simply don't provide any wrapper function and leave it to the end users? |
I think this may need a larger diff description showing exactly why an operation's operands are not appropriate but extra passed in operands are. This sounds like wanting to call the function while the IR is invalid, but if the IR is invalid then many of these functions could be wrong (and one would also need to probably avoid using accessors generated on the operation).
mlir/include/mlir/Interfaces/InferTypeOpInterface.td | ||
---|---|---|
166 | Bufferization is an exceptional case of usage of dialect conversion, it is the odd one out compared to most uses of dialect conversion. |
mlir/include/mlir/Interfaces/InferTypeOpInterface.td | ||
---|---|---|
166 | Thanks. When the matchAndRewrite method of a conversion pattern is called, I think the op itself is still valid (e.g. attributes, output types) except that the operands may have been converted to other types, leading calling getOperand unsafely. To solve this problem, this interface follows the design of the conversion pattern, that is, accepting passed in operands to avoid calling getOperand directly inside the interface implementation. |
@herhut Hi, I remove the original interface and only keep the one accepting passed in operands. Could you take a look again?
@jpienaar Hi, I add some additional descriptions. Could you help to take a look again?
mlir/include/mlir/Interfaces/InferTypeOpInterface.td | ||
---|---|---|
166 | It is true that bufferization is special in many ways but I think the general contract in DialectConversion is that one shall not look at he ops' operands directly but only use the passed in operands arrayref. | |
mlir/test/lib/Dialect/Test/TestDialect.cpp | ||
754 | If you update the signature, you also need to update the inner workings of this function. it should now use operants.front() or something like that. |
mlir/test/lib/Dialect/Test/TestDialect.cpp | ||
---|---|---|
754 | Thanks! I have fixed it. |
@herhut Hi, I don't have commit access to the llvm repo at the moment. Could you please help me to merge this patch? Thanks!
Do we really need two versions of this function here?
I'd prefer to only have the variant with explicit operands at the interface level. What is now a default implementation of the existing interface could instead be just a helper/wrapper that can be used when the operands are the actual operands.
This has the disadvantage that we would need to refactor all implementations and users of this interface. Longer term, it has the big advantage that the interfaces cannot go out of sync.