[Mlir-commits] [mlir] [mlir][vector] Add deinterleave operation to vector dialect (PR #92409)

Mubashar Ahmad llvmlistbot at llvm.org
Tue May 21 04:22:05 PDT 2024


================
@@ -543,6 +543,82 @@ def Vector_InterleaveOp :
   }];
 }
 
+class ResultIsHalfSourceVectorType<string result> : TypesMatchWith<
+  "the trailing dimension of the results is half the width of source trailing dimension",
+  "source", result,
+  [{
+    [&]() -> ::mlir::VectorType {
+      auto vectorType = ::llvm::cast<mlir::VectorType>($_self);
+      ::mlir::VectorType::Builder builder(vectorType);
+      auto lastDim = vectorType.getRank() - 1;
+      auto newDimSize = vectorType.getDimSize(lastDim) / 2;;
+      if (newDimSize <= 0)
+         return vectorType; // (invalid input type)
+      return builder.setDim(lastDim, newDimSize);
+    }()
+  }]
+>;
+
+class SourceVectorEvenElementCount : PredOpTrait<"the trailing dimension of the source vector has an even number of elements",
+    CPred<[{
+      [&](){
+        auto srcVec = getSourceVectorType();
+        return srcVec.getDimSize(srcVec.getRank() - 1) % 2 == 0;
+      }()
+    }]>
+>;
+
+def Vector_DeinterleaveOp :
+  Vector_Op<"deinterleave", [Pure,
+    SourceVectorEvenElementCount<>,
+    ResultIsHalfSourceVectorType<"res1">,
+    ResultIsHalfSourceVectorType<"res2">,
+    AllTypesMatch<["res1", "res2"]>
+    ]> {
+      let summary = "constructs two vectors by deinterleaving an input vector";
+      let description = [{
+        The deinterleave operation constructs two vectors from a single input
+        vector. The first result vector contains the elements from even indexes
+        of the input, and the second contains elements from odd indexes. This is
+        the inverse of a 'vector.interleave' operation.
+
+        Each output's trailing dimension is half of the size of the input
+        vector's trailing dimension. This operation requires the input vector
+        to have a rank > 0 and an even number of elements in its trailing
+        dimension.
+
+        The operation supports scalable vectors.
+
+        Example:
+        ```mlir
+        %0, %1 = vector.deinterleave %a
+                   : vector<[4]xi32> into vector<[2]xi32>, vector<[2]xi32>
+        %2, %3 = vector.deinterleave %b
+                   : vector<8xi8> into vector<4xi8>, vector<4xi8>
+        %4, %5 = vector.deinterleave %c
+                   : vector<2x8xf32> into vector<2x4xf32>, vector<2x4xf32>
+        %6, %7 = vector.deinterleave %d
+                   : vector<2x4x[6]xf64> into vector<2x4x[3]xf64>, vector<2x4x[3]xf64>
+        ```
+      }];
+
+      let arguments = (ins AnyVector:$source);
+      let results = (outs AnyVector:$res1, AnyVector:$res2);
+
+      let assemblyFormat = [{
+        $source attr-dict `:` type($source)
+      }];
----------------
mub-at-arm wrote:

@MacDue, @kuhar, I've added and `assemblyFormat` that fully describes the operation without being too verbose. An "x2" suffix on the result describes the quantity of that type quite simply and should be easily readable too.

So the resulting IR should look like this:
`%1, %2 = vector.deinterleave %a : vector<4xf32> -> vector<2xf32>x2`



https://github.com/llvm/llvm-project/pull/92409


More information about the Mlir-commits mailing list