Separating the AffineMapAccessInterface from AffineRead/WriteOp interface so that dialects which extend Affine capabilities (e.g. PlaidML PXA = parallel extensions for Affine) can utilize relevant passes (e.g. MemRef normalization).
Details
Diff Detail
Event Timeline
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
151 | The name should refer to its connection with affine maps. std.load dereferences a memref just fine, but this interfaces wouldn't make sense for it. Something like AffineMapAccessInterface would be more suitable. | |
165 | The interface arguments is only used for this assertion. Let's drop both the argument and the assertion... | |
mlir/lib/Transforms/Utils/Utils.cpp | ||
86 | Use cast instead of dyn_cast if you don't check the result of cast for nullity. Also, avoid using (dyn_)cast immediately after isa. Something like auto derefInterface = dyn_cast<MemRefDereferencingInterface>(op); if (!derefInterface) { // ... return ...; } NamedAttribute oldMapAttrPair = derefInterface.getAffineMapAttr(); should work here |
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
165 | One of the primary reasons for making this interface is to allow support for memref normalization of other operations not defined in this repo. For our use case, this includes an operation which does affine dereferencing of multiple memrefs, so the argument is required to link the memref to the appropriate AffineMapAttr. |
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
165 | Then it needs to be appropriately documented. We have no knowledge of downstream projects and we can easily remove the code that is useless in core without warning unless it is clear from the code or documentation that it serves some purpose. |
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
165 | Note that AffineDmaStartOp uses this interface and provides a non-default implementation of the getAffineMapAttrForMemRef method which returns a different AffineMap depending on whether the src or dst MemRef is passed in. I will update the description to make this more clear, as well. |
Maybe there's something off on my side but I can't see the diff between the last version of the patch (Diff 3) and Base. When I set up that view in "Revision Contents->History", it shows the Diff against a previous version of the patch, which doesn't include all the changes. Something seems to be off.
Apologize for the patching issues. I believe I have corrected the problem now. Diff 322729 shows all my intended changes from base.
It works after the last update. Thanks!
LGTM. Some minor comments. Please, wait for @ftynse's final approval.
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
154–155 |
| |
mlir/include/mlir/Dialect/Affine/IR/AffineOps.h | ||
309 | Maybe adding a comment here about this being the implementation of a method of the new AffineMapAccessInterface interface would be useful. |
Thanks for making the "memref deferencing ops" thing more systematic here. This is looking good to me. Mostly polishing and doc related comments.
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
153–154 | I think we really need a couple more lines explaining the meaning of the interface better (especially for new users). For eg., there is an implication that the memref is being dereferenced / accessed - you actually have it in the name of the interface but this isn't reflected in the description here. | |
165–167 | Assertion message please. | |
mlir/lib/Transforms/Utils/Utils.cpp | ||
75–76 | Better name here: affMapAcc -> affMapAccInterface (no increase in number of lines due to this). |
mlir/lib/Transforms/Utils/Utils.cpp | ||
---|---|---|
31 | This isn't the only user of such a utility: /lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp:64:static bool isMemRefDereferencingOp(Operation &op) { ./lib/Transforms/LoopFusion.cpp:72:static bool isMemRefDereferencingOp(Operation &op) { Can we remove those as well? |
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
153–154 | I still find this documentation not direct/complete enough when read by a new user. It's missing information that clearly specifies which ops should be implementing this interface. Consider rephrasing along: access a given memref -> dereference and access a given memref operand | |
154 | assume -> assumes | |
154 | default implementation -> current implementation? | |
155 | to -> on | |
158–161 | You won't need a set method in the future? | |
166 | to match operation memref -> to match memref operand | |
mlir/include/mlir/Dialect/Affine/IR/AffineOps.td | ||
757 | Nit: Update comment for the renamed argument. | |
mlir/lib/Transforms/Utils/Utils.cpp | ||
263–265 | Drop trivial braces - unrelated change as well. | |
267–269 | Likewise - inadvertent change unrelated to this revision. |
mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.td | ||
---|---|---|
154 | The reference to the "default implementation" in the description was done to address earlier comments regarding the need to pass in the memref to the interface at all + the need for the assert memref == op.getMemRef() in the default implementation. The reason for this is that operations implementing the interface can operate on more than one memref. I have the description to say that --- "Implementers of this interface must operate on at least one memref operand." I hope this clears things up. | |
158–161 | I would prefer to address this in the future, as needed. |
The name should refer to its connection with affine maps. std.load dereferences a memref just fine, but this interfaces wouldn't make sense for it. Something like AffineMapAccessInterface would be more suitable.