Skip to content

[mlir][Interface] Factor out common IndexingMapOpInterface behavior in a new generic interface #145313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 24, 2025

Conversation

nicolasvasilache
Copy link
Contributor

@nicolasvasilache nicolasvasilache commented Jun 23, 2025

Refactor the verifiers to make use of the common bits and make vector.contract also use this interface.
In the process, the confusingly named getStaticShape has disappeared.

Note: the verifier for IndexingMapOpInterface is currently called manually from other verifiers as it was unclear how to avoid it taking precedence over more meaningful error messages

@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2025

@llvm/pr-subscribers-mlir-linalg
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-vector

Author: Nicolas Vasilache (nicolasvasilache)

Changes

…contract


Full diff: https://github.com/llvm/llvm-project/pull/145313.diff

1 Files Affected:

  • (modified) mlir/include/mlir/Dialect/Vector/IR/VectorOps.td (+33)
diff --git a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
index 926a92eff2ebb..7ac661d8bbf69 100644
--- a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
@@ -207,6 +207,39 @@ def Vector_ContractionOp :
               .template getAsValueRange<IteratorTypeAttr, IteratorType>();
       return {range.begin(), range.end()};
     }
+
+    //===------------------------------------------------------------------===//
+    // The code below is shared with LinalgStructuredInterface.
+    // vector.contract is really a linalg.generic on vectors without region.
+    // TODO: factor out in a common interface to inherit from ince identified.
+    //===------------------------------------------------------------------===//
+    ArrayRef<int64_t> getShape(OpOperand * opOperand) {
+      assert(opOperand->getOwner() == this->getOperation());
+      Type t = opOperand->get().getType();
+      return cast<VectorType>(t).getShape();
+    }
+
+    AffineMap getLoopsToShapesMap() {
+      auto maps = getIndexingMapsArray();
+      return concatAffineMaps(maps);
+    }
+
+    AffineMap getShapesToLoopsMap() {
+      return inversePermutation(getLoopsToShapesMap());
+    }
+
+    SmallVector<int64_t> getStaticShape(){
+      SmallVector<int64_t> res;
+      for (OpOperand &opOperand : this->getOperation()->getOpOperands())
+        llvm::append_range(res, getShape(&opOperand));
+      return res;
+    }
+
+    SmallVector<int64_t> getStaticLoopRanges() {
+      SmallVector<int64_t> viewSizes = getStaticShape();
+      AffineMap invertedMap = getShapesToLoopsMap();
+      return invertedMap.compose(viewSizes);
+    }
   }];
 
   let hasCanonicalizer = 1;

@nicolasvasilache nicolasvasilache force-pushed the users/nico/vector-structured-iface branch from a1373fb to 91f7ea2 Compare June 23, 2025 11:47
nicolasvasilache added a commit to nicolasvasilache/iree that referenced this pull request Jun 23, 2025
This allows external systems to make use of IREE's vector_distribute functionality in a composable manner.
This depends on llvm/llvm-project#145313 landing and being integrated into IREE.

Signed-off-by: Nicolas Vasilache <[email protected]>
Copy link
Contributor

@fabianmcg fabianmcg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but add comments pointing each member to the corresponding LinalgStructuredInterface method, otherwise the methods appear undocumented and it's unclear what they do without looking at the header.

NIT, fix description.

@fabianmcg fabianmcg changed the title [mlir][vector] NFC - Add more structured interface support to vector.… [mlir][vector] NFC - Add more structured interface support to vector. contract Jun 23, 2025
@fabianmcg fabianmcg changed the title [mlir][vector] NFC - Add more structured interface support to vector. contract [mlir][vector] NFC - Add more structured interface support to vector.contract Jun 23, 2025
Copy link
Member

@Groverkss Groverkss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better implementation would to add these methods to IndexingMapOpInterface and make vector.contract implement it.

@fabianmcg
Copy link
Contributor

fabianmcg commented Jun 23, 2025

I think a better implementation would to add these methods to IndexingMapOpInterface and make vector.contract implement it.

I agree, but that's a can of worms in RFCs, as we don't have a structured directory to put the interface in (we should have one).

@Groverkss
Copy link
Member

I think a better implementation would to add these methods to IndexingMapOpInterface and make vector.contract implement it.

I agree, but that's a can of worms in RFCs, as we don't have a structured directory to put the interface in (we should have one).

I don't think it is. The Interface lives in lib/Interfaces right?

@fabianmcg
Copy link
Contributor

I don't think it is. The Interface lives in lib/Interfaces right?

Nope: https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Linalg/IR/LinalgInterfaces.td#L225

@banach-space
Copy link
Contributor

I'm OK with this change in principle, but we should either add dedicated tests or ensure there are in-tree uses of this interface. Otherwise, it becomes "dead code," and there's nothing stopping it from being removed in the future by someone upstream.

@nicolasvasilache
Copy link
Contributor Author

@rengolin @Groverkss @banach-space I have a WIP followup to put stuff in lib/Interface but I think I am limited atm.

TL;DR:

  1. getShape should not be the same implementation for Linalg and Vector (i.e. Linalg<memref> is a useful thing to have and thus vector would be an "elemental type" for Linalg but a "ShapedType" for vector)
  2. the other methods to factor out in IndexingMapOpInterface want to make use of getShape, so it needs a default impl to be seen by the IndexingMapOpInterface
  3. it seems there is a limitation on interface inheritance, where an interface cannot override, atm I have the following case:
    a. IndexingMapOpInterface -> Vector::ContractOp seems fine
    b. IndexingMapOpInterface -> LinalgStructuredInterface -> Linalg::XXXOp does not seem to be fine
  4. I don't want to have to individually override in each Linalg::XXXOp

I can put up a followup PR and we can discuss there

@nicolasvasilache
Copy link
Contributor Author

I'm OK with this change in principle, but we should either add dedicated tests or ensure there are in-tree uses of this interface. Otherwise, it becomes "dead code," and there's nothing stopping it from being removed in the future by someone upstream.

good point !

@nicolasvasilache
Copy link
Contributor Author

#145332 if someone sees a way to do this better

@Groverkss
Copy link
Member

#145332 if someone sees a way to do this better

I like that PR much more. I think we should go with that instead.

Copy link
Member

@Groverkss Groverkss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! This is really nice and will be good for other operations as well.

I think there is an issue with dps interface implementation and indexingmapopinterface being in opposite files, but rest lgtm.

Also, would be good to change the pr title.

@nicolasvasilache nicolasvasilache changed the title [mlir][vector] NFC - Add more structured interface support to vector.contract [mlir][Interface] Factor out common IndexingMapOpInterface behavior in a new generic interface Jun 23, 2025
@nicolasvasilache nicolasvasilache force-pushed the users/nico/vector-structured-iface branch from 8b3665b to 8e819cf Compare June 23, 2025 15:54
@nicolasvasilache nicolasvasilache force-pushed the users/nico/vector-structured-iface branch from 8e819cf to 6c53f21 Compare June 23, 2025 15:59
@nicolasvasilache
Copy link
Contributor Author

#145332 if someone sees a way to do this better

I like that PR much more. I think we should go with that instead.

@ftynse helped me figure out what was wrong, it was an instance of the infamous /*methodBody=*/"" vs /*defaultImplementation=*/[{}] case ...

@nicolasvasilache nicolasvasilache force-pushed the users/nico/vector-structured-iface branch from c563af4 to ef7ee8e Compare June 24, 2025 05:43
@nicolasvasilache nicolasvasilache merged commit d31ba52 into main Jun 24, 2025
5 of 7 checks passed
@nicolasvasilache nicolasvasilache deleted the users/nico/vector-structured-iface branch June 24, 2025 05:56
DrSergei pushed a commit to DrSergei/llvm-project that referenced this pull request Jun 24, 2025
…n a new generic interface (llvm#145313)

Refactor the verifiers to make use of the common bits and make
`vector.contract` also use this interface.
In the process, the confusingly named getStaticShape has disappeared.

Note: the verifier for IndexingMapOpInterface is currently called
manually from other verifiers as it was unclear how to avoid it taking
precedence over more meaningful error messages
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants