[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread via llvm-branch-commits

MaheshRavishankar wrote:

> I think @MaheshRavishankar should take a look at the interface implementation 
> details.

Actually @Max191 or @harsh-nod  have most context on the interface 
implementation details. I actually dont care as much as long as it isnt 
changing the interface implementation details. I wont be able to do a detailed 
review for this, but if there is a specific issue that seems off, please 
upsignal.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2776,6 +2776,15 @@ LogicalResult WinogradFilterTransformOp::verify() {
 // WinogradInputTransformOp
 
//===--===//
 
+Value getValueFromOpFoldResult(OpFoldResult opFoldResult, OpBuilder ,
+   Location loc) {
+  if (auto attr = opFoldResult.dyn_cast()) {
+auto intAttr = cast(attr);
+return builder.create(loc, intAttr);
+  }
+  return opFoldResult.get();
+}

ftynse wrote:

https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Arith/Utils/Utils.h#L68-L72
 it already exists

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2810,9 +2819,117 @@ LogicalResult WinogradInputTransformOp::verify() {
   if (failed(verifyCompatibleShape(expectedOutputShape, outputShape))) {
 return emitOpError("the output shape is not expected");
   }
+
   return success();
 }
 
+SmallVector
+WinogradInputTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  auto indexType = builder.getIndexType();
+  auto zeroAttr = builder.getIntegerAttr(indexType, 0);
+  auto oneAttr = builder.getIntegerAttr(indexType, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zeroAttr;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = oneAttr;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradInputTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+LogicalResult WinogradInputTransformOp::getResultTilePosition(
+OpBuilder , unsigned resultNumber, ArrayRef offsets,
+ArrayRef sizes, SmallVector ,
+SmallVector ) {
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  auto oneAttr = builder.getI64IntegerAttr(1);
+
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(offsets[2]);
+  resultOffsets.push_back(offsets[3]);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultSizes.push_back(sizes[0]);
+  resultSizes.push_back(sizes[1]);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(sizes[4]);
+  resultSizes.push_back(sizes[5]);
+
+  return success();
+}
+
+FailureOr
+WinogradInputTransformOp::getTiledImplementation(OpBuilder ,
+ ArrayRef 
offsets,
+ ArrayRef sizes) 
{
+  auto oneAttr = builder.getI64IntegerAttr(1);
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  Value input = getInput();
+  auto inputType = cast(input.getType());
+  auto inputShape = inputType.getShape();

ftynse wrote:

Here and below.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2810,9 +2819,117 @@ LogicalResult WinogradInputTransformOp::verify() {
   if (failed(verifyCompatibleShape(expectedOutputShape, outputShape))) {
 return emitOpError("the output shape is not expected");
   }
+
   return success();
 }
 
+SmallVector
+WinogradInputTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  auto indexType = builder.getIndexType();
+  auto zeroAttr = builder.getIntegerAttr(indexType, 0);
+  auto oneAttr = builder.getIntegerAttr(indexType, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zeroAttr;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = oneAttr;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradInputTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+LogicalResult WinogradInputTransformOp::getResultTilePosition(
+OpBuilder , unsigned resultNumber, ArrayRef offsets,
+ArrayRef sizes, SmallVector ,
+SmallVector ) {
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  auto oneAttr = builder.getI64IntegerAttr(1);
+
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(offsets[2]);
+  resultOffsets.push_back(offsets[3]);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultSizes.push_back(sizes[0]);
+  resultSizes.push_back(sizes[1]);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(sizes[4]);
+  resultSizes.push_back(sizes[5]);
+
+  return success();
+}
+
+FailureOr
+WinogradInputTransformOp::getTiledImplementation(OpBuilder ,
+ ArrayRef 
offsets,
+ ArrayRef sizes) 
{
+  auto oneAttr = builder.getI64IntegerAttr(1);
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  Value input = getInput();
+  auto inputType = cast(input.getType());
+  auto inputShape = inputType.getShape();
+  int64_t inputH = inputShape[1];
+  int64_t inputW = inputShape[2];
+  int64_t m = getM();
+  int64_t r = getR();
+  int64_t alpha = m + r - 1;
+  int64_t alphaH = inputH != 1 ? alpha : 1;
+  int64_t alphaW = inputW != 1 ? alpha : 1;
+  auto alphaHAttr = builder.getI64IntegerAttr(alphaH);
+  auto alphaWAttr = builder.getI64IntegerAttr(alphaW);
+
+  Location loc = getLoc();
+  SmallVector tiledOperands;
+  SmallVector sliceOffsets, sliceSizes;
+
+  auto context = builder.getContext();
+  auto affineMap =
+  AffineMap::get(1, 0, {builder.getAffineDimExpr(0) * m}, context);
+  Value mappedOffset1 = builder.create(
+  loc, affineMap, getValueFromOpFoldResult(offsets[2], builder, loc));
+  Value mappedOffset2 = builder.create(
+  loc, affineMap, getValueFromOpFoldResult(offsets[3], builder, loc));
+
+  sliceOffsets.push_back(zeroAttr);
+  sliceOffsets.push_back(mappedOffset1);
+  sliceOffsets.push_back(mappedOffset2);
+  sliceOffsets.push_back(zeroAttr);
+  sliceSizes.push_back(sizes[4]);
+  sliceSizes.push_back(alphaHAttr);
+  sliceSizes.push_back(alphaWAttr);
+  sliceSizes.push_back(sizes[5]);
+  SmallVector inputStrides(4, oneAttr);
+  tiledOperands.emplace_back(builder.create(
+  loc, getInput(), sliceOffsets, sliceSizes, inputStrides));
+
+  sliceOffsets.clear();
+  sliceSizes.clear();
+  if (failed(getResultTilePosition(builder, 1, offsets, sizes, sliceOffsets,
+   sliceSizes)))
+return failure();
+
+  SmallVector outputStrides(6, oneAttr);
+  tiledOperands.emplace_back(builder.create(
+  loc, getOutput(), sliceOffsets, sliceSizes, outputStrides));
+
+  SmallVector resultTypes;

ftynse wrote:

```suggestion
  SmallVector resultTypes;
```

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits

https://github.com/ftynse commented:

Looks okay to me in general. Something went wrong with rebases so I see code 
that doesn't belong to this change. Let me know when you merged the bases and I 
can click-approve this one.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2810,9 +2819,117 @@ LogicalResult WinogradInputTransformOp::verify() {
   if (failed(verifyCompatibleShape(expectedOutputShape, outputShape))) {
 return emitOpError("the output shape is not expected");
   }
+
   return success();
 }
 
+SmallVector
+WinogradInputTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  auto indexType = builder.getIndexType();
+  auto zeroAttr = builder.getIntegerAttr(indexType, 0);
+  auto oneAttr = builder.getIntegerAttr(indexType, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zeroAttr;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = oneAttr;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradInputTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+LogicalResult WinogradInputTransformOp::getResultTilePosition(
+OpBuilder , unsigned resultNumber, ArrayRef offsets,
+ArrayRef sizes, SmallVector ,
+SmallVector ) {
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  auto oneAttr = builder.getI64IntegerAttr(1);
+
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(offsets[2]);
+  resultOffsets.push_back(offsets[3]);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultSizes.push_back(sizes[0]);
+  resultSizes.push_back(sizes[1]);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(sizes[4]);
+  resultSizes.push_back(sizes[5]);
+
+  return success();
+}
+
+FailureOr
+WinogradInputTransformOp::getTiledImplementation(OpBuilder ,
+ ArrayRef 
offsets,
+ ArrayRef sizes) 
{
+  auto oneAttr = builder.getI64IntegerAttr(1);
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  Value input = getInput();
+  auto inputType = cast(input.getType());
+  auto inputShape = inputType.getShape();
+  int64_t inputH = inputShape[1];
+  int64_t inputW = inputShape[2];
+  int64_t m = getM();
+  int64_t r = getR();
+  int64_t alpha = m + r - 1;
+  int64_t alphaH = inputH != 1 ? alpha : 1;
+  int64_t alphaW = inputW != 1 ? alpha : 1;
+  auto alphaHAttr = builder.getI64IntegerAttr(alphaH);
+  auto alphaWAttr = builder.getI64IntegerAttr(alphaW);
+
+  Location loc = getLoc();
+  SmallVector tiledOperands;
+  SmallVector sliceOffsets, sliceSizes;
+
+  auto context = builder.getContext();
+  auto affineMap =
+  AffineMap::get(1, 0, {builder.getAffineDimExpr(0) * m}, context);
+  Value mappedOffset1 = builder.create(
+  loc, affineMap, getValueFromOpFoldResult(offsets[2], builder, loc));
+  Value mappedOffset2 = builder.create(
+  loc, affineMap, getValueFromOpFoldResult(offsets[3], builder, loc));
+
+  sliceOffsets.push_back(zeroAttr);
+  sliceOffsets.push_back(mappedOffset1);
+  sliceOffsets.push_back(mappedOffset2);
+  sliceOffsets.push_back(zeroAttr);
+  sliceSizes.push_back(sizes[4]);
+  sliceSizes.push_back(alphaHAttr);
+  sliceSizes.push_back(alphaWAttr);
+  sliceSizes.push_back(sizes[5]);
+  SmallVector inputStrides(4, oneAttr);
+  tiledOperands.emplace_back(builder.create(
+  loc, getInput(), sliceOffsets, sliceSizes, inputStrides));
+
+  sliceOffsets.clear();
+  sliceSizes.clear();

ftynse wrote:

I'd rather declare new vectors for this.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits

https://github.com/ftynse edited https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2810,9 +2819,117 @@ LogicalResult WinogradInputTransformOp::verify() {
   if (failed(verifyCompatibleShape(expectedOutputShape, outputShape))) {
 return emitOpError("the output shape is not expected");
   }
+
   return success();
 }
 
+SmallVector
+WinogradInputTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  auto indexType = builder.getIndexType();
+  auto zeroAttr = builder.getIntegerAttr(indexType, 0);
+  auto oneAttr = builder.getIntegerAttr(indexType, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zeroAttr;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = oneAttr;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradInputTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+LogicalResult WinogradInputTransformOp::getResultTilePosition(
+OpBuilder , unsigned resultNumber, ArrayRef offsets,
+ArrayRef sizes, SmallVector ,
+SmallVector ) {
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  auto oneAttr = builder.getI64IntegerAttr(1);
+
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(offsets[2]);
+  resultOffsets.push_back(offsets[3]);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultSizes.push_back(sizes[0]);
+  resultSizes.push_back(sizes[1]);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(sizes[4]);
+  resultSizes.push_back(sizes[5]);
+
+  return success();
+}
+
+FailureOr
+WinogradInputTransformOp::getTiledImplementation(OpBuilder ,
+ ArrayRef 
offsets,
+ ArrayRef sizes) 
{
+  auto oneAttr = builder.getI64IntegerAttr(1);
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  Value input = getInput();
+  auto inputType = cast(input.getType());
+  auto inputShape = inputType.getShape();

ftynse wrote:

Please expand `auto` unless the type is obvious from statement-level context 
(builders on the RHS are fine, but I don't remember what `getShape` returns as 
a type).

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-11 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2810,9 +2819,117 @@ LogicalResult WinogradInputTransformOp::verify() {
   if (failed(verifyCompatibleShape(expectedOutputShape, outputShape))) {
 return emitOpError("the output shape is not expected");
   }
+
   return success();
 }
 
+SmallVector
+WinogradInputTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  auto indexType = builder.getIndexType();
+  auto zeroAttr = builder.getIntegerAttr(indexType, 0);
+  auto oneAttr = builder.getIntegerAttr(indexType, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zeroAttr;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = oneAttr;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradInputTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+LogicalResult WinogradInputTransformOp::getResultTilePosition(
+OpBuilder , unsigned resultNumber, ArrayRef offsets,
+ArrayRef sizes, SmallVector ,
+SmallVector ) {
+  auto zeroAttr = builder.getI64IntegerAttr(0);
+  auto oneAttr = builder.getI64IntegerAttr(1);
+
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(offsets[2]);
+  resultOffsets.push_back(offsets[3]);
+  resultOffsets.push_back(zeroAttr);
+  resultOffsets.push_back(zeroAttr);
+  resultSizes.push_back(sizes[0]);
+  resultSizes.push_back(sizes[1]);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(oneAttr);
+  resultSizes.push_back(sizes[4]);
+  resultSizes.push_back(sizes[5]);

ftynse wrote:

Nit: something like `resultOffsets.append({zeroAttr, zeroAttr, offsets[2], 
offsets[3], zeroAttr, zeroAttr})` may be more readable.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-01 Thread Hsiangkai Wang via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zero;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = one;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradFilterTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+Value getValueFromOpFoldResult(OpFoldResult opFoldResult, OpBuilder ,
+   Location loc) {
+  if (auto val = opFoldResult.dyn_cast()) {
+return val;
+  } else if (auto attr = opFoldResult.dyn_cast()) {
+auto intAttr = cast(attr);
+return builder.create(loc, intAttr);
+  }
+  // This should never happen if OpFoldResult is correctly formed.

Hsiangkai wrote:

I updated the implementation.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-01 Thread Hsiangkai Wang via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);

Hsiangkai wrote:

Done.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-01 Thread Hsiangkai Wang via llvm-branch-commits


@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg

Hsiangkai wrote:

Done.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-07-01 Thread Hsiangkai Wang via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zero;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = one;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradFilterTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+Value getValueFromOpFoldResult(OpFoldResult opFoldResult, OpBuilder ,
+   Location loc) {
+  if (auto val = opFoldResult.dyn_cast()) {
+return val;
+  } else if (auto attr = opFoldResult.dyn_cast()) {
+auto intAttr = cast(attr);
+return builder.create(loc, intAttr);
+  }

Hsiangkai wrote:

I only find a similar one in `mlir/lib/Dialect/Vector/IR/VectorOps.cpp` under 
`vector` namespace. It is to convert an array of `OpFoldResult` to an array of 
`Value`.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg

ftynse wrote:

Nit: operations

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zero;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = one;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradFilterTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+Value getValueFromOpFoldResult(OpFoldResult opFoldResult, OpBuilder ,
+   Location loc) {
+  if (auto val = opFoldResult.dyn_cast()) {
+return val;
+  } else if (auto attr = opFoldResult.dyn_cast()) {
+auto intAttr = cast(attr);
+return builder.create(loc, intAttr);
+  }
+  // This should never happen if OpFoldResult is correctly formed.

ftynse wrote:

Then this should be an assertion.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);

ftynse wrote:

IIRC, `Range` contains list of `OpFoldResult`, meaning we can put attributes 
there and not materialize operations for these constants.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits


@@ -2760,6 +2760,89 @@ LogicalResult WinogradFilterTransformOp::verify() {
   return success();
 }
 
+SmallVector
+WinogradFilterTransformOp::getIterationDomain(OpBuilder ) {
+  Location loc = getLoc();
+  Value zero = builder.create(loc, 0);
+  Value one = builder.create(loc, 1);
+  Value output = getOutput();
+  SmallVector loopBounds(6);
+  for (unsigned dim = 0; dim < 6; ++dim) {
+loopBounds[dim].offset = zero;
+loopBounds[dim].size = getDimValue(builder, loc, output, dim);
+loopBounds[dim].stride = one;
+  }
+  return loopBounds;
+}
+
+SmallVector
+WinogradFilterTransformOp::getLoopIteratorTypes() {
+  SmallVector iteratorTypes(6,
+ 
utils::IteratorType::parallel);
+  return iteratorTypes;
+}
+
+Value getValueFromOpFoldResult(OpFoldResult opFoldResult, OpBuilder ,
+   Location loc) {
+  if (auto val = opFoldResult.dyn_cast()) {
+return val;
+  } else if (auto attr = opFoldResult.dyn_cast()) {
+auto intAttr = cast(attr);
+return builder.create(loc, intAttr);
+  }

ftynse wrote:

I suspect this might already exist somewhere in the arith dialect.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits

https://github.com/ftynse commented:

I think @MaheshRavishankar should take a look at the interface implementation 
details.

https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-24 Thread Oleksandr Alex Zinenko via llvm-branch-commits

https://github.com/ftynse edited https://github.com/llvm/llvm-project/pull/96184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-20 Thread Hsiangkai Wang via llvm-branch-commits

https://github.com/Hsiangkai updated 
https://github.com/llvm/llvm-project/pull/96184

>From 73b524b7746839614655fd8082dbda297e93ba72 Mon Sep 17 00:00:00 2001
From: Hsiangkai Wang 
Date: Mon, 17 Jun 2024 11:44:27 +0100
Subject: [PATCH 1/2] [mlir][linalg] Implement TilingInterface for winograd
 operators

In order to support arbitrary size input data of conv2d, implement
TilingInterface for winograd operators. Before converting winograd
operators into nested loops with matrix multiply, tile the input of
conv2d into the supported size first.

Add a transform operator structured.decompose_winograd_op to decompose
winograd operators. Before applying the transform op, use tile_using_for
to tile the input data into supported size. The test case shows how to
tile and decompose winograd operators.
---
 .../mlir/Dialect/Linalg/IR/LinalgOps.td   |  21 +-
 .../Linalg/TransformOps/LinalgTransformOps.td |  37 ++
 .../Dialect/Linalg/Transforms/Transforms.h|  45 +++
 mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp  | 281 +++
 .../TransformOps/LinalgTransformOps.cpp   |  27 ++
 .../Linalg/Transforms/WinogradConv2D.cpp  |  18 +
 .../transform-tile-and-winograd-rewrite.mlir  | 332 ++
 7 files changed, 758 insertions(+), 3 deletions(-)
 create mode 100644 
mlir/test/Dialect/Linalg/transform-tile-and-winograd-rewrite.mlir

diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td 
b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index de1097b6ac27b..45726d6ee2224 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -154,7 +154,12 @@ def Linalg_SoftmaxOp : Linalg_Op<"softmax",
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform"> {
+def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd filter transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -192,7 +197,12 @@ def Linalg_WinogradFilterTransformOp : 
Linalg_Op<"winograd_filter_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform"> {
+def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd input transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -230,7 +240,12 @@ def Linalg_WinogradInputTransformOp : 
Linalg_Op<"winograd_input_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform"> {
+def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd output transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
diff --git 
a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td 
b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 68d0f713caad4..71736eae38b4f 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg
+equivalent operators. Before applying this transform operator, users
+need to tile winograd transform operators into supported sizes.
+
+ Return modes:
+
+This operation fails if `target` is unsupported. Otherwise, the operation
+succeeds and returns a handle of the sequence that replaces the original
+operator.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs TransformHandleTypeInterface:$transformed);
+
+  let assemblyFormat =
+"$target attr-dict `:` functional-type($target, results)";
+
+  let builders = [
+OpBuilder<(ins "Value":$target)>
+  ];
+
+  let extraClassDeclaration = [{
+::mlir::DiagnosedSilenceableFailure applyToOne(
+::mlir::transform::TransformRewriter ,
+::mlir::Operation *target,
+::mlir::transform::ApplyToEachResultList ,
+::mlir::transform::TransformState );
+  }];
+}
+
 #endif // LINALG_TRANSFORM_OPS
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index bb7ec590faad0..d0eec2be1f8fb 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1319,6 +1319,51 @@ FailureOr winogradConv2D(RewriterBase 
,
   linalg::Conv2DNhwcFhwcOp op, 

[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-20 Thread Hsiangkai Wang via llvm-branch-commits

https://github.com/Hsiangkai updated 
https://github.com/llvm/llvm-project/pull/96184

>From 73b524b7746839614655fd8082dbda297e93ba72 Mon Sep 17 00:00:00 2001
From: Hsiangkai Wang 
Date: Mon, 17 Jun 2024 11:44:27 +0100
Subject: [PATCH] [mlir][linalg] Implement TilingInterface for winograd
 operators

In order to support arbitrary size input data of conv2d, implement
TilingInterface for winograd operators. Before converting winograd
operators into nested loops with matrix multiply, tile the input of
conv2d into the supported size first.

Add a transform operator structured.decompose_winograd_op to decompose
winograd operators. Before applying the transform op, use tile_using_for
to tile the input data into supported size. The test case shows how to
tile and decompose winograd operators.
---
 .../mlir/Dialect/Linalg/IR/LinalgOps.td   |  21 +-
 .../Linalg/TransformOps/LinalgTransformOps.td |  37 ++
 .../Dialect/Linalg/Transforms/Transforms.h|  45 +++
 mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp  | 281 +++
 .../TransformOps/LinalgTransformOps.cpp   |  27 ++
 .../Linalg/Transforms/WinogradConv2D.cpp  |  18 +
 .../transform-tile-and-winograd-rewrite.mlir  | 332 ++
 7 files changed, 758 insertions(+), 3 deletions(-)
 create mode 100644 
mlir/test/Dialect/Linalg/transform-tile-and-winograd-rewrite.mlir

diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td 
b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index de1097b6ac27b..45726d6ee2224 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -154,7 +154,12 @@ def Linalg_SoftmaxOp : Linalg_Op<"softmax",
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform"> {
+def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd filter transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -192,7 +197,12 @@ def Linalg_WinogradFilterTransformOp : 
Linalg_Op<"winograd_filter_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform"> {
+def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd input transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -230,7 +240,12 @@ def Linalg_WinogradInputTransformOp : 
Linalg_Op<"winograd_input_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform"> {
+def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd output transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
diff --git 
a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td 
b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 68d0f713caad4..71736eae38b4f 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg
+equivalent operators. Before applying this transform operator, users
+need to tile winograd transform operators into supported sizes.
+
+ Return modes:
+
+This operation fails if `target` is unsupported. Otherwise, the operation
+succeeds and returns a handle of the sequence that replaces the original
+operator.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs TransformHandleTypeInterface:$transformed);
+
+  let assemblyFormat =
+"$target attr-dict `:` functional-type($target, results)";
+
+  let builders = [
+OpBuilder<(ins "Value":$target)>
+  ];
+
+  let extraClassDeclaration = [{
+::mlir::DiagnosedSilenceableFailure applyToOne(
+::mlir::transform::TransformRewriter ,
+::mlir::Operation *target,
+::mlir::transform::ApplyToEachResultList ,
+::mlir::transform::TransformState );
+  }];
+}
+
 #endif // LINALG_TRANSFORM_OPS
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index bb7ec590faad0..d0eec2be1f8fb 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1319,6 +1319,51 @@ FailureOr winogradConv2D(RewriterBase 
,
   linalg::Conv2DNhwcFhwcOp op, int64_t 

[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-20 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-mlir

Author: Hsiangkai Wang (Hsiangkai)


Changes

In order to support arbitrary size input data of conv2d, implement 
TilingInterface for winograd operators. Before converting winograd operators 
into nested loops with matrix multiply, tile the input of conv2d into the 
supported size first.

Add a transform operator structured.decompose_winograd_op to decompose winograd 
operators. Before applying the transform op, use tile_using_for to tile the 
input data into supported size. The test case shows how to tile and decompose 
winograd operators.

---

Patch is 58.85 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/96184.diff


7 Files Affected:

- (modified) mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td (+18-3) 
- (modified) 
mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td (+37) 
- (modified) mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h (+45) 
- (modified) mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp (+281) 
- (modified) mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp (+27) 
- (modified) mlir/lib/Dialect/Linalg/Transforms/WinogradConv2D.cpp (+18) 
- (added) mlir/test/Dialect/Linalg/transform-tile-and-winograd-rewrite.mlir 
(+332) 


``diff
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td 
b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index de1097b6ac27b..45726d6ee2224 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -154,7 +154,12 @@ def Linalg_SoftmaxOp : Linalg_Op<"softmax",
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform"> {
+def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd filter transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -192,7 +197,12 @@ def Linalg_WinogradFilterTransformOp : 
Linalg_Op<"winograd_filter_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform"> {
+def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd input transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -230,7 +240,12 @@ def Linalg_WinogradInputTransformOp : 
Linalg_Op<"winograd_input_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform"> {
+def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd output transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
diff --git 
a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td 
b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 68d0f713caad4..71736eae38b4f 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg
+equivalent operators. Before applying this transform operator, users
+need to tile winograd transform operators into supported sizes.
+
+ Return modes:
+
+This operation fails if `target` is unsupported. Otherwise, the operation
+succeeds and returns a handle of the sequence that replaces the original
+operator.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs TransformHandleTypeInterface:$transformed);
+
+  let assemblyFormat =
+"$target attr-dict `:` functional-type($target, results)";
+
+  let builders = [
+OpBuilder<(ins "Value":$target)>
+  ];
+
+  let extraClassDeclaration = [{
+::mlir::DiagnosedSilenceableFailure applyToOne(
+::mlir::transform::TransformRewriter ,
+::mlir::Operation *target,
+::mlir::transform::ApplyToEachResultList ,
+::mlir::transform::TransformState );
+  }];
+}
+
 #endif // LINALG_TRANSFORM_OPS
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index bb7ec590faad0..d0eec2be1f8fb 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1319,6 +1319,51 @@ FailureOr winogradConv2D(RewriterBase 
,
   linalg::Conv2DNhwcFhwcOp op, int64_t m,
   int64_t r);
 
+/// Rewrite 

[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-20 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-mlir-linalg

Author: Hsiangkai Wang (Hsiangkai)


Changes

In order to support arbitrary size input data of conv2d, implement 
TilingInterface for winograd operators. Before converting winograd operators 
into nested loops with matrix multiply, tile the input of conv2d into the 
supported size first.

Add a transform operator structured.decompose_winograd_op to decompose winograd 
operators. Before applying the transform op, use tile_using_for to tile the 
input data into supported size. The test case shows how to tile and decompose 
winograd operators.

---

Patch is 58.85 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/96184.diff


7 Files Affected:

- (modified) mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td (+18-3) 
- (modified) 
mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td (+37) 
- (modified) mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h (+45) 
- (modified) mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp (+281) 
- (modified) mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp (+27) 
- (modified) mlir/lib/Dialect/Linalg/Transforms/WinogradConv2D.cpp (+18) 
- (added) mlir/test/Dialect/Linalg/transform-tile-and-winograd-rewrite.mlir 
(+332) 


``diff
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td 
b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index de1097b6ac27b..45726d6ee2224 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -154,7 +154,12 @@ def Linalg_SoftmaxOp : Linalg_Op<"softmax",
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform"> {
+def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd filter transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -192,7 +197,12 @@ def Linalg_WinogradFilterTransformOp : 
Linalg_Op<"winograd_filter_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform"> {
+def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd input transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -230,7 +240,12 @@ def Linalg_WinogradInputTransformOp : 
Linalg_Op<"winograd_input_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform"> {
+def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd output transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
diff --git 
a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td 
b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 68d0f713caad4..71736eae38b4f 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg
+equivalent operators. Before applying this transform operator, users
+need to tile winograd transform operators into supported sizes.
+
+ Return modes:
+
+This operation fails if `target` is unsupported. Otherwise, the operation
+succeeds and returns a handle of the sequence that replaces the original
+operator.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs TransformHandleTypeInterface:$transformed);
+
+  let assemblyFormat =
+"$target attr-dict `:` functional-type($target, results)";
+
+  let builders = [
+OpBuilder<(ins "Value":$target)>
+  ];
+
+  let extraClassDeclaration = [{
+::mlir::DiagnosedSilenceableFailure applyToOne(
+::mlir::transform::TransformRewriter ,
+::mlir::Operation *target,
+::mlir::transform::ApplyToEachResultList ,
+::mlir::transform::TransformState );
+  }];
+}
+
 #endif // LINALG_TRANSFORM_OPS
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index bb7ec590faad0..d0eec2be1f8fb 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1319,6 +1319,51 @@ FailureOr winogradConv2D(RewriterBase 
,
   linalg::Conv2DNhwcFhwcOp op, int64_t m,
   int64_t r);
 
+/// 

[llvm-branch-commits] [mlir] [mlir][linalg] Implement TilingInterface for winograd operators (PR #96184)

2024-06-20 Thread Hsiangkai Wang via llvm-branch-commits

https://github.com/Hsiangkai created 
https://github.com/llvm/llvm-project/pull/96184

In order to support arbitrary size input data of conv2d, implement 
TilingInterface for winograd operators. Before converting winograd operators 
into nested loops with matrix multiply, tile the input of conv2d into the 
supported size first.

Add a transform operator structured.decompose_winograd_op to decompose winograd 
operators. Before applying the transform op, use tile_using_for to tile the 
input data into supported size. The test case shows how to tile and decompose 
winograd operators.

>From 7300578082fb321a0617ed2b61202eca39989e59 Mon Sep 17 00:00:00 2001
From: Hsiangkai Wang 
Date: Mon, 17 Jun 2024 11:44:27 +0100
Subject: [PATCH] [mlir][linalg] Implement TilingInterface for winograd
 operators

In order to support arbitrary size input data of conv2d, implement
TilingInterface for winograd operators. Before converting winograd
operators into nested loops with matrix multiply, tile the input of
conv2d into the supported size first.

Add a transform operator structured.decompose_winograd_op to decompose
winograd operators. Before applying the transform op, use tile_using_for
to tile the input data into supported size. The test case shows how to
tile and decompose winograd operators.
---
 .../mlir/Dialect/Linalg/IR/LinalgOps.td   |  21 +-
 .../Linalg/TransformOps/LinalgTransformOps.td |  37 ++
 .../Dialect/Linalg/Transforms/Transforms.h|  45 +++
 mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp  | 281 +++
 .../TransformOps/LinalgTransformOps.cpp   |  27 ++
 .../Linalg/Transforms/WinogradConv2D.cpp  |  18 +
 .../transform-tile-and-winograd-rewrite.mlir  | 332 ++
 7 files changed, 758 insertions(+), 3 deletions(-)
 create mode 100644 
mlir/test/Dialect/Linalg/transform-tile-and-winograd-rewrite.mlir

diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td 
b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index de1097b6ac27b..45726d6ee2224 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -154,7 +154,12 @@ def Linalg_SoftmaxOp : Linalg_Op<"softmax",
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform"> {
+def Linalg_WinogradFilterTransformOp : Linalg_Op<"winograd_filter_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd filter transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -192,7 +197,12 @@ def Linalg_WinogradFilterTransformOp : 
Linalg_Op<"winograd_filter_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform"> {
+def Linalg_WinogradInputTransformOp : Linalg_Op<"winograd_input_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd input transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
@@ -230,7 +240,12 @@ def Linalg_WinogradInputTransformOp : 
Linalg_Op<"winograd_input_transform"> {
   let hasVerifier = 1;
 }
 
-def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform"> {
+def Linalg_WinogradOutputTransformOp : Linalg_Op<"winograd_output_transform",
+[DeclareOpInterfaceMethods]> {
   let summary = "Winograd output transform operator";
   let description = [{
 Winograd Conv2D algorithm will convert linalg Conv2D operator into batched
diff --git 
a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td 
b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 68d0f713caad4..71736eae38b4f 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -2638,4 +2638,41 @@ def WinogradConv2DOp : Op {
+  let description = [{
+Decompose winograd operators. It will convert filter, input and output
+transform operators into a combination of scf, tensor, and linalg
+equivalent operators. Before applying this transform operator, users
+need to tile winograd transform operators into supported sizes.
+
+ Return modes:
+
+This operation fails if `target` is unsupported. Otherwise, the operation
+succeeds and returns a handle of the sequence that replaces the original
+operator.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs TransformHandleTypeInterface:$transformed);
+
+  let assemblyFormat =
+"$target attr-dict `:` functional-type($target, results)";
+
+  let builders = [
+OpBuilder<(ins "Value":$target)>
+  ];
+
+  let extraClassDeclaration = [{
+::mlir::DiagnosedSilenceableFailure applyToOne(
+::mlir::transform::TransformRewriter ,
+::mlir::Operation *target,
+::mlir::transform::ApplyToEachResultList ,
+