[Mlir-commits] [mlir] fc81a66 - [NFC][Linalg] Add `matchConvolutionOpOfType` API and make `isaConvolutionOpOfType` API a wrapper (#174722)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Jan 13 22:20:38 PST 2026
Author: Abhishek Varma
Date: 2026-01-14T06:20:33Z
New Revision: fc81a665133fe757741d68f07245d5f696a65346
URL: https://github.com/llvm/llvm-project/commit/fc81a665133fe757741d68f07245d5f696a65346
DIFF: https://github.com/llvm/llvm-project/commit/fc81a665133fe757741d68f07245d5f696a65346.diff
LOG: [NFC][Linalg] Add `matchConvolutionOpOfType` API and make `isaConvolutionOpOfType` API a wrapper (#174722)
-- This commit involves the following updates pertaining to
`isaConvolutionOpOfType` API :-
1. We don't want dilations/strides of convolution op to be returned as
pointer arguments to the API function - to tackle this we create a new
API `matchConvolutionOpOfType` which would return an optional struct of
dilations/stride.
2. To not break the original API's use case as a simple querying
functionality with true/false return - we keep `isaConvolutionOpOfType`
as a wrapper API which will invoke `matchConvolutionOpOfType` API and
return true/false depending on whether `matchConvolutionOpOfType` API
returned any value or not.
3. Dilations/strides of named convolution op are also populated now (it
was missed in the previous PRs while creating `isaConvolutionOpOfType`).
4. [Max/Min]UnsignedPool ops' body matcher now only matches unsigned int
ops (refer: https://github.com/llvm/llvm-project/pull/166070)
-- No tests are being added as all the above are NFC changes around the
API which already is being tested via Specialize.cpp.
Signed-off-by: Abhishek Varma <abhvarma at amd.com>
Added:
Modified:
mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
mlir/lib/Dialect/Linalg/Utils/Utils.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
index 9da01f30b52d2..06e7a472a8182 100644
--- a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
+++ b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
@@ -106,12 +106,26 @@ getReassociationMapForFoldingUnitDims(ArrayRef<OpFoldResult> mixedSizes);
// Convolution matcher utility
//===----------------------------------------------------------------------===//
-/// Given a linalg `op` this function returns true if it is a convolution op of
-/// type `ConvOpTy` and populates `dilations` and `strides` with values inferred
-/// from the indexing maps.
+/// A struct containing dilations and strides inferred from convolution ops.
+struct DilationsAndStrides {
+ SmallVector<int64_t> dilations;
+ SmallVector<int64_t> strides;
+};
+
+/// Given a linalg `op` this function returns DilationsAndStrides if it is a
+/// convolution op of type `ConvOpTy`, otherwise returns std::nullopt. The
+/// dilations and strides are inferred from the indexing maps. For ops like
+/// Conv1DOp, Conv2DOp and Conv3DOp that have no strides/dilations attributes,
+/// defaults of [1, ...] are returned for both.
template <typename ConvOpTy>
-bool isaConvolutionOpOfType(LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides);
+std::optional<DilationsAndStrides> matchConvolutionOpOfType(LinalgOp op);
+
+/// Returns true if the linalg `op` is a convolution op of type `ConvOpTy`.
+/// This is a convenience wrapper around matchConvolutionOpOfType.
+template <typename ConvOpTy>
+bool isaConvolutionOpOfType(LinalgOp op) {
+ return matchConvolutionOpOfType<ConvOpTy>(op).has_value();
+}
//===----------------------------------------------------------------------===//
// Fusion / Tiling utilities
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp b/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
index 0c7b998ffcab9..da062152f61ad 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
@@ -267,11 +267,11 @@ specializeToConvOp(RewriterBase &rewriter, GenericOp genericOp,
/// Converts linalg.generic to named linalg.*conv/pooling* where possible.
static FailureOr<LinalgOp> specializeLinalgConvolutions(RewriterBase &rewriter,
GenericOp genericOp) {
- SmallVector<int64_t> dilations, strides;
#define CONV_OP_SPECIALIZER(ConvOpTy) \
- if (isaConvolutionOpOfType<ConvOpTy>(genericOp, &dilations, &strides)) \
- return specializeToConvOp<ConvOpTy>(rewriter, genericOp, dilations, \
- strides); \
+ if (std::optional<DilationsAndStrides> convParams = \
+ matchConvolutionOpOfType<ConvOpTy>(genericOp)) \
+ return specializeToConvOp<ConvOpTy>( \
+ rewriter, genericOp, convParams->dilations, convParams->strides); \
// -----------------------------
// Convolution ops.
// -----------------------------
diff --git a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
index 2718124251c18..4e1731ddcfd45 100644
--- a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
+++ b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
@@ -373,11 +373,8 @@ static bool bodyMatcherForMaxSignedPoolOps(Value yieldVal, Block *body) {
body);
}
-// max_unsigned ops should not allow float data type.
-// TODO(#164800): Retire OPDSL logic.
static bool bodyMatcherForMaxUnsignedPoolOps(Value yieldVal, Block *body) {
- return bodyMatcherForPoolOps<arith::MaximumFOp, arith::MaxUIOp>(yieldVal,
- body);
+ return bodyMatcherForPoolOps<arith::MaxUIOp>(yieldVal, body);
}
static bool bodyMatcherForMinSignedPoolOps(Value yieldVal, Block *body) {
@@ -385,11 +382,8 @@ static bool bodyMatcherForMinSignedPoolOps(Value yieldVal, Block *body) {
body);
}
-// min_unsigned ops should not allow float data type.
-// TODO(#164800): Retire OPDSL logic.
static bool bodyMatcherForMinUnsignedPoolOps(Value yieldVal, Block *body) {
- return bodyMatcherForPoolOps<arith::MinimumFOp, arith::MinUIOp>(yieldVal,
- body);
+ return bodyMatcherForPoolOps<arith::MinUIOp>(yieldVal, body);
}
static bool bodyMatcherForSumPoolOps(Value yieldVal, Block *body) {
@@ -598,109 +592,142 @@ class ConvMatcherBuilder {
//===----------------------------------------------------------------------===//
template <>
-bool isaConvolutionOpOfType<linalg::Conv1DOp>(LinalgOp op,
- SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv1DOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv1DOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (isa<linalg::Conv1DOp>(op)) {
+ // Conv1DOp has no strides/dilations attributes, default to 1.
+ result.dilations = SmallVector<int64_t>(1, 1);
+ result.strides = SmallVector<int64_t>(1, 1);
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr W = m.dim(0);
AffineExpr w = m.dim(1);
- return m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
- .matchMaps({/*inputMap=*/{m.strided(W, w, 0)},
- /*filterMap=*/{w},
- /*outputMap=*/{W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{m.strided(W, w, 0)},
+ /*filterMap=*/{w},
+ /*outputMap=*/{W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv1DNwcWcfOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv1DNwcWcfOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv1DNwcWcfOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv1DNwcWcfOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr F = m.dim(2);
AffineExpr w = m.dim(3);
AffineExpr c = m.dim(4);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), c},
- /*filterMap=*/{w, c, F},
- /*outputMap=*/{N, W, F}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), c},
+ /*filterMap=*/{w, c, F},
+ /*outputMap=*/{N, W, F}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv1DNcwFcwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv1DNcwFcwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv1DNcwFcwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv1DNcwFcwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr F = m.dim(1);
AffineExpr W = m.dim(2);
AffineExpr c = m.dim(3);
AffineExpr w = m.dim(4);
- return m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, c, m.strided(W, w, 0)},
- /*filterMap=*/{F, c, w},
- /*outputMap=*/{N, F, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, c, m.strided(W, w, 0)},
+ /*filterMap=*/{F, c, w},
+ /*outputMap=*/{N, F, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DOp>(LinalgOp op,
- SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (isa<linalg::Conv2DOp>(op)) {
+ // Conv2DOp has no strides/dilations attributes, default to 1.
+ result.dilations = SmallVector<int64_t>(2, 1);
+ result.strides = SmallVector<int64_t>(2, 1);
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr H = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr h = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
- .matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/1)
- .matchMaps({/*inputMap=*/{m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{h, w},
- /*outputMap=*/{H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
+ .matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/1)
+ .matchMaps({/*inputMap=*/{m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwcHwcfOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwcHwcfOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwcHwcfOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwcHwcfOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -709,25 +736,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcHwcfOp>(
AffineExpr w = m.dim(5);
AffineExpr c = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
- /*filterMap=*/{h, w, c, F},
- /*outputMap=*/{N, H, W, F}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
+ /*filterMap=*/{h, w, c, F},
+ /*outputMap=*/{N, H, W, F}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwcHwcfQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwcHwcfQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwcHwcfQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwcHwcfQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -736,27 +771,35 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcHwcfQOp>(
AffineExpr w = m.dim(5);
AffineExpr c = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
- /*filterMap=*/{h, w, c, F},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, H, W, F}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
+ /*filterMap=*/{h, w, c, F},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, H, W, F}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwcFhwcOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwcFhwcOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwcFhwcOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwcFhwcOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -765,25 +808,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcFhwcOp>(
AffineExpr w = m.dim(5);
AffineExpr c = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
- /*filterMap=*/{F, h, w, c},
- /*outputMap=*/{N, H, W, F}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
+ /*filterMap=*/{F, h, w, c},
+ /*outputMap=*/{N, H, W, F}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwcFhwcQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwcFhwcQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwcFhwcQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwcFhwcQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -792,27 +843,35 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcFhwcQOp>(
AffineExpr w = m.dim(5);
AffineExpr c = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
- /*filterMap=*/{F, h, w, c},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, H, W, F}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), c},
+ /*filterMap=*/{F, h, w, c},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, H, W, F}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNchwFchwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNchwFchwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNchwFchwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNchwFchwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr F = m.dim(1);
AffineExpr H = m.dim(2);
@@ -821,25 +880,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNchwFchwOp>(
AffineExpr h = m.dim(5);
AffineExpr w = m.dim(6);
- return m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, c, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{F, c, h, w},
- /*outputMap=*/{N, F, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, c, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{F, c, h, w},
+ /*outputMap=*/{N, F, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNchwFchwQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNchwFchwQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNchwFchwQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNchwFchwQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr F = m.dim(1);
AffineExpr H = m.dim(2);
@@ -848,27 +915,35 @@ bool isaConvolutionOpOfType<linalg::Conv2DNchwFchwQOp>(
AffineExpr h = m.dim(5);
AffineExpr w = m.dim(6);
- return m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, c, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{F, c, h, w},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, F, H, W}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, c, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{F, c, h, w},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, F, H, W}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNgchwFgchwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNgchwFgchwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNgchwFgchwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNgchwFgchwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr G = m.dim(1);
AffineExpr F = m.dim(2);
@@ -878,26 +953,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNgchwFgchwOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
- .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
- .matchMaps(
- {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{F, G, c, h, w},
- /*outputMap=*/{N, G, F, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
+ .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{F, G, c, h, w},
+ /*outputMap=*/{N, G, F, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNgchwGfchwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNgchwGfchwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNgchwGfchwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNgchwGfchwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr G = m.dim(1);
AffineExpr F = m.dim(2);
@@ -907,26 +989,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNgchwGfchwOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
- .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
- .matchMaps(
- {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{G, F, c, h, w},
- /*outputMap=*/{N, G, F, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
+ .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{G, F, c, h, w},
+ /*outputMap=*/{N, G, F, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNgchwGfchwQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNgchwGfchwQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNgchwGfchwQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNgchwGfchwQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr G = m.dim(1);
AffineExpr F = m.dim(2);
@@ -936,28 +1025,35 @@ bool isaConvolutionOpOfType<linalg::Conv2DNgchwGfchwQOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
- .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
- .matchMaps(
- {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{G, F, c, h, w},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, G, F, H, W}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/0)
+ .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, G, c, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{G, F, c, h, w},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, G, F, H, W}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwgcGfhwcOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwgcGfhwcOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -967,26 +1063,33 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcOp>(
AffineExpr w = m.dim(6);
AffineExpr c = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/2, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/3, /*oDim=*/2, /*idx=*/1)
- .matchMaps(
- {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), G, c},
- /*filterMap=*/{G, F, h, w, c},
- /*outputMap=*/{N, H, W, G, F}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/2, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/3, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), G, c},
+ /*filterMap=*/{G, F, h, w, c},
+ /*outputMap=*/{N, H, W, G, F}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv2DNhwgcGfhwcQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv2DNhwgcGfhwcQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -996,28 +1099,35 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcQOp>(
AffineExpr w = m.dim(6);
AffineExpr c = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/2, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/3, /*oDim=*/2, /*idx=*/1)
- .matchMaps(
- {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), G, c},
- /*filterMap=*/{G, F, h, w, c},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, H, W, G, F}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/2, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/3, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), G, c},
+ /*filterMap=*/{G, F, h, w, c},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, H, W, G, F}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv3DOp>(LinalgOp op,
- SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv3DOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv3DOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (isa<linalg::Conv3DOp>(op)) {
+ // Conv3DOp has no strides/dilations attributes, default to 1.
+ result.dilations = SmallVector<int64_t>(3, 1);
+ result.strides = SmallVector<int64_t>(3, 1);
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr D = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1025,27 +1135,34 @@ bool isaConvolutionOpOfType<linalg::Conv3DOp>(LinalgOp op,
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
- .matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/1)
- .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/2)
- .matchMaps({/*inputMap=*/{m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2)},
- /*filterMap=*/{d, h, w},
- /*outputMap=*/{D, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/0, /*fDim=*/0, /*oDim=*/0, /*idx=*/0)
+ .matchStride(/*iDim=*/1, /*fDim=*/1, /*oDim=*/1, /*idx=*/1)
+ .matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2)},
+ /*filterMap=*/{d, h, w},
+ /*outputMap=*/{D, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv3DNdhwcDhwcfOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv3DNdhwcDhwcfOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1056,27 +1173,34 @@ bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfOp>(
AffineExpr w = m.dim(7);
AffineExpr c = m.dim(8);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), c},
- /*filterMap=*/{d, h, w, c, F},
- /*outputMap=*/{N, D, H, W, F}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), c},
+ /*filterMap=*/{d, h, w, c, F},
+ /*outputMap=*/{N, D, H, W, F}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv3DNdhwcDhwcfQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv3DNdhwcDhwcfQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1087,29 +1211,36 @@ bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfQOp>(
AffineExpr w = m.dim(7);
AffineExpr c = m.dim(8);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), c},
- /*filterMap=*/{d, h, w, c, F},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, D, H, W, F}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), c},
+ /*filterMap=*/{d, h, w, c, F},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, D, H, W, F}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::Conv3DNcdhwFcdhwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::Conv3DNcdhwFcdhwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::Conv3DNcdhwFcdhwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp = dyn_cast<linalg::Conv3DNcdhwFcdhwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr F = m.dim(1);
AffineExpr D = m.dim(2);
@@ -1120,97 +1251,129 @@ bool isaConvolutionOpOfType<linalg::Conv3DNcdhwFcdhwOp>(
AffineExpr h = m.dim(7);
AffineExpr w = m.dim(8);
- return m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
- .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, c, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2)},
- /*filterMap=*/{F, c, d, h, w},
- /*outputMap=*/{N, F, D, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
+ .matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, c, m.strided(D, d, 0),
+ m.strided(H, h, 1), m.strided(W, w, 2)},
+ /*filterMap=*/{F, c, d, h, w},
+ /*outputMap=*/{N, F, D, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv1DNcwCwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv1DNcwCwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv1DNcwCwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv1DNcwCwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
- /*filterMap=*/{C, w},
- /*outputMap=*/{N, C, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
+ /*filterMap=*/{C, w},
+ /*outputMap=*/{N, C, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv1DNwcWcOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv1DNwcWcOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv1DNwcWcOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv1DNwcWcOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w, C},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w, C},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv1DNwcWcmOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv1DNwcWcmOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv1DNwcWcmOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv1DNwcWcmOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr CM = m.dim(3);
AffineExpr w = m.dim(4);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w, C, CM},
- /*outputMap=*/{N, W, C, CM}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w, C, CM},
+ /*outputMap=*/{N, W, C, CM}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNchwChwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv2DNchwChwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv2DNchwChwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv2DNchwChwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1218,25 +1381,34 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNchwChwOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{C, h, w},
- /*outputMap=*/{N, C, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{C, h, w},
+ /*outputMap=*/{N, C, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv2DNhwcHwcOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv2DNhwcHwcOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1244,25 +1416,34 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w, C},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w, C},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv2DNhwcHwcQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv2DNhwcHwcQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1270,27 +1451,36 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcQOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w, C},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, H, W, C}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w, C},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv2DNhwcHwcmOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv2DNhwcHwcmOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1299,25 +1489,34 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmOp>(
AffineExpr h = m.dim(5);
AffineExpr w = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w, C, CM},
- /*outputMap=*/{N, H, W, C, CM}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w, C, CM},
+ /*outputMap=*/{N, H, W, C, CM}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmQOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv2DNhwcHwcmQOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmQOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv2DNhwcHwcmQOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1326,27 +1525,36 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmQOp>(
AffineExpr h = m.dim(5);
AffineExpr w = m.dim(6);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w, C, CM},
- /*scalarMap=*/{},
- /*scalarMap=*/{},
- /*outputMap=*/{N, H, W, C, CM}})
- .matchBody(/*containsZeroPointOffset=*/true);
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w, C, CM},
+ /*scalarMap=*/{},
+ /*scalarMap=*/{},
+ /*outputMap=*/{N, H, W, C, CM}})
+ .matchBody(/*containsZeroPointOffset=*/true))
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv3DNdhwcDhwcOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv3DNdhwcDhwcOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1356,27 +1564,35 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcOp>(
AffineExpr w = m.dim(6);
AffineExpr C = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), C},
- /*filterMap=*/{d, h, w, C},
- /*outputMap=*/{N, D, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), C},
+ /*filterMap=*/{d, h, w, C},
+ /*outputMap=*/{N, D, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNcdhwCdhwOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv3DNcdhwCdhwOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv3DNcdhwCdhwOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv3DNcdhwCdhwOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1386,27 +1602,35 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNcdhwCdhwOp>(
AffineExpr w = m.dim(6);
AffineExpr C = m.dim(7);
- return m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/1)
- .matchStride(/*iDim=*/4, /*fDim=*/3, /*oDim=*/4, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, C, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2)},
- /*filterMap=*/{C, d, h, w},
- /*outputMap=*/{N, C, D, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/1)
+ .matchStride(/*iDim=*/4, /*fDim=*/3, /*oDim=*/4, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, C, m.strided(D, d, 0),
+ m.strided(H, h, 1), m.strided(W, w, 2)},
+ /*filterMap=*/{C, d, h, w},
+ /*outputMap=*/{N, C, D, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcmOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::DepthwiseConv3DNdhwcDhwcmOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcmOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto convOp =
+ dyn_cast<linalg::DepthwiseConv3DNdhwcDhwcmOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(convOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(convOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1417,28 +1641,34 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcmOp>(
AffineExpr w = m.dim(7);
AffineExpr C = m.dim(8);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), C},
- /*filterMap=*/{d, h, w, C, CM},
- /*outputMap=*/{N, D, H, W, C, CM}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), C},
+ /*filterMap=*/{d, h, w, C, CM},
+ /*outputMap=*/{N, D, H, W, C, CM}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNhwcMaxOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNhwcMaxOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNhwcMaxOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNhwcMaxOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::MaxSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::MaxSigned);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1446,26 +1676,33 @@ bool isaConvolutionOpOfType<linalg::PoolingNhwcMaxOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNhwcMinOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNhwcMinOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNhwcMinOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNhwcMinOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::MinSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::MinSigned);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1473,26 +1710,33 @@ bool isaConvolutionOpOfType<linalg::PoolingNhwcMinOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNhwcSumOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNhwcSumOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNhwcSumOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNhwcSumOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::Sum);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::Sum);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1500,26 +1744,34 @@ bool isaConvolutionOpOfType<linalg::PoolingNhwcSumOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNhwcMaxUnsignedOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNhwcMaxUnsignedOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNhwcMaxUnsignedOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp =
+ dyn_cast<linalg::PoolingNhwcMaxUnsignedOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::MaxUnsigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::MaxUnsigned);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1527,26 +1779,34 @@ bool isaConvolutionOpOfType<linalg::PoolingNhwcMaxUnsignedOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNhwcMinUnsignedOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNhwcMinUnsignedOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNhwcMinUnsignedOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp =
+ dyn_cast<linalg::PoolingNhwcMinUnsignedOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::MinUnsigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::MinUnsigned);
AffineExpr N = m.dim(0);
AffineExpr H = m.dim(1);
AffineExpr W = m.dim(2);
@@ -1554,26 +1814,33 @@ bool isaConvolutionOpOfType<linalg::PoolingNhwcMinUnsignedOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, m.strided(H, h, 0), m.strided(W, w, 1), C},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNchwSumOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNchwSumOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNchwSumOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNchwSumOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::Sum);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::Sum);
AffineExpr N = m.dim(0);
AffineExpr C = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1581,26 +1848,33 @@ bool isaConvolutionOpOfType<linalg::PoolingNchwSumOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/1, /*oDim=*/3, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, C, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/1, /*oDim=*/3, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, C, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNchwMaxOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNchwMaxOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNchwMaxOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNchwMaxOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/2, dilations, strides,
- PoolingType::MaxSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/2, &result.dilations,
+ &result.strides, PoolingType::MaxSigned);
AffineExpr N = m.dim(0);
AffineExpr C = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1608,194 +1882,245 @@ bool isaConvolutionOpOfType<linalg::PoolingNchwMaxOp>(
AffineExpr h = m.dim(4);
AffineExpr w = m.dim(5);
- return m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
- .matchStride(/*iDim=*/3, /*fDim=*/1, /*oDim=*/3, /*idx=*/1)
- .matchMaps({/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
- /*filterMap=*/{h, w},
- /*outputMap=*/{N, C, H, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
+ .matchStride(/*iDim=*/3, /*fDim=*/1, /*oDim=*/3, /*idx=*/1)
+ .matchMaps(
+ {/*inputMap=*/{N, C, m.strided(H, h, 0), m.strided(W, w, 1)},
+ /*filterMap=*/{h, w},
+ /*outputMap=*/{N, C, H, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNwcSumOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNwcSumOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNwcSumOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNwcSumOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::Sum);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::Sum);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNcwSumOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNcwSumOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNcwSumOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNcwSumOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::Sum);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::Sum);
AffineExpr N = m.dim(0);
AffineExpr C = m.dim(1);
AffineExpr W = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
- /*filterMap=*/{w},
- /*outputMap=*/{N, C, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, C, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNwcMaxOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNwcMaxOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNwcMaxOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNwcMaxOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::MaxSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::MaxSigned);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNwcMaxUnsignedOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNwcMaxUnsignedOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNwcMaxUnsignedOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp =
+ dyn_cast<linalg::PoolingNwcMaxUnsignedOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::MaxUnsigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::MaxUnsigned);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNcwMaxOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNcwMaxOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNcwMaxOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNcwMaxOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::MaxSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::MaxSigned);
AffineExpr N = m.dim(0);
AffineExpr C = m.dim(1);
AffineExpr W = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
- /*filterMap=*/{w},
- /*outputMap=*/{N, C, W}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/2, /*fDim=*/0, /*oDim=*/2, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, C, m.strided(W, w, 0)},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, C, W}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNwcMinOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNwcMinOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNwcMinOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNwcMinOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::MinSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::MinSigned);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNwcMinUnsignedOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNwcMinUnsignedOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNwcMinUnsignedOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp =
+ dyn_cast<linalg::PoolingNwcMinUnsignedOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/1, dilations, strides,
- PoolingType::MinUnsigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/1, &result.dilations,
+ &result.strides, PoolingType::MinUnsigned);
AffineExpr N = m.dim(0);
AffineExpr W = m.dim(1);
AffineExpr C = m.dim(2);
AffineExpr w = m.dim(3);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
- /*filterMap=*/{w},
- /*outputMap=*/{N, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchMaps({/*inputMap=*/{N, m.strided(W, w, 0), C},
+ /*filterMap=*/{w},
+ /*outputMap=*/{N, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNdhwcSumOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNdhwcSumOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNdhwcSumOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNdhwcSumOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides,
- PoolingType::Sum);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides, PoolingType::Sum);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1805,28 +2130,34 @@ bool isaConvolutionOpOfType<linalg::PoolingNdhwcSumOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), C},
- /*filterMap=*/{d, h, w},
- /*outputMap=*/{N, D, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), C},
+ /*filterMap=*/{d, h, w},
+ /*outputMap=*/{N, D, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNdhwcMaxOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNdhwcMaxOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNdhwcMaxOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNdhwcMaxOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides,
- PoolingType::MaxSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides, PoolingType::MaxSigned);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1836,28 +2167,34 @@ bool isaConvolutionOpOfType<linalg::PoolingNdhwcMaxOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), C},
- /*filterMap=*/{d, h, w},
- /*outputMap=*/{N, D, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), C},
+ /*filterMap=*/{d, h, w},
+ /*outputMap=*/{N, D, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
template <>
-bool isaConvolutionOpOfType<linalg::PoolingNdhwcMinOp>(
- LinalgOp op, SmallVector<int64_t> *dilations,
- SmallVector<int64_t> *strides) {
- if (isa<linalg::PoolingNdhwcMinOp>(op))
- return true;
+std::optional<DilationsAndStrides>
+matchConvolutionOpOfType<linalg::PoolingNdhwcMinOp>(LinalgOp op) {
+ DilationsAndStrides result;
+ if (auto poolOp = dyn_cast<linalg::PoolingNdhwcMinOp>(op.getOperation())) {
+ result.dilations =
+ llvm::to_vector(poolOp.getDilations().getValues<int64_t>());
+ result.strides = llvm::to_vector(poolOp.getStrides().getValues<int64_t>());
+ return result;
+ }
assert(isaConvolutionOpInterface(op) &&
"expected op to implement ConvolutionOpInterface");
- ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides,
- PoolingType::MinSigned);
+ ConvMatcherBuilder m(op, /*spatialRank=*/3, &result.dilations,
+ &result.strides, PoolingType::MinSigned);
AffineExpr N = m.dim(0);
AffineExpr D = m.dim(1);
AffineExpr H = m.dim(2);
@@ -1867,14 +2204,16 @@ bool isaConvolutionOpOfType<linalg::PoolingNdhwcMinOp>(
AffineExpr h = m.dim(6);
AffineExpr w = m.dim(7);
- return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
- .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
- .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
- .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
- m.strided(W, w, 2), C},
- /*filterMap=*/{d, h, w},
- /*outputMap=*/{N, D, H, W, C}})
- .matchBody();
+ if (m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
+ .matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
+ .matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
+ .matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
+ m.strided(W, w, 2), C},
+ /*filterMap=*/{d, h, w},
+ /*outputMap=*/{N, D, H, W, C}})
+ .matchBody())
+ return result;
+ return std::nullopt;
}
Value makeComposedPadHighOp(OpBuilder &b, Location loc, RankedTensorType type,
More information about the Mlir-commits
mailing list