Skip to content

Commit 59b128c

Browse files
[Linalg] Add *Conv3D* matchers
-- This commit is the sixth in the series of adding matchers for linalg.*conv*/*pool*. Refer: #163724 -- In this commit all variants of Conv3D convolution ops have been added. Signed-off-by: Abhishek Varma <[email protected]>
1 parent c81d449 commit 59b128c

File tree

3 files changed

+253
-9
lines changed

3 files changed

+253
-9
lines changed

mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ static FailureOr<LinalgOp> specializeLinalgConvolutions(RewriterBase &rewriter,
291291
CONV_OP_SPECIALIZER(linalg::Conv2DNhwgcGfhwcOp);
292292
CONV_OP_SPECIALIZER(linalg::Conv2DNhwgcGfhwcQOp);
293293
CONV_OP_SPECIALIZER(linalg::Conv3DOp);
294+
CONV_OP_SPECIALIZER(linalg::Conv3DNdhwcDhwcfOp);
295+
CONV_OP_SPECIALIZER(linalg::Conv3DNdhwcDhwcfQOp);
296+
CONV_OP_SPECIALIZER(linalg::Conv3DNcdhwFcdhwOp);
294297
// -----------------------------
295298
// Depthwise Convolution ops.
296299
// -----------------------------
@@ -302,6 +305,8 @@ static FailureOr<LinalgOp> specializeLinalgConvolutions(RewriterBase &rewriter,
302305
CONV_OP_SPECIALIZER(linalg::DepthwiseConv2DNhwcHwcQOp);
303306
CONV_OP_SPECIALIZER(linalg::DepthwiseConv2DNhwcHwcmOp);
304307
CONV_OP_SPECIALIZER(linalg::DepthwiseConv2DNhwcHwcmQOp);
308+
CONV_OP_SPECIALIZER(linalg::DepthwiseConv3DNdhwcDhwcOp);
309+
CONV_OP_SPECIALIZER(linalg::DepthwiseConv3DNcdhwCdhwOp);
305310
CONV_OP_SPECIALIZER(linalg::DepthwiseConv3DNdhwcDhwcmOp);
306311
// -----------------------------
307312
// Pooling ops.

mlir/lib/Dialect/Linalg/Utils/Utils.cpp

Lines changed: 183 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -569,15 +569,15 @@ class ConvMatcherBuilder {
569569
}
570570

571571
/// Match body pattern. This should be called last.
572-
bool matchBody(bool zeroPointOffset = false) {
572+
bool matchBody(bool containsZeroPointOffset = false) {
573573
if (!matched)
574574
return false;
575575
Block *body = op.getBlock();
576576
auto yieldOp = cast<linalg::YieldOp>(body->getTerminator());
577577
switch (poolingType) {
578578
case PoolingType::None:
579579
return bodyMatcherForConvolutionOps(yieldOp.getOperand(0), body,
580-
zeroPointOffset);
580+
containsZeroPointOffset);
581581
case PoolingType::MaxSigned:
582582
return bodyMatcherForMaxSignedPoolOps(yieldOp.getOperand(0), body);
583583
case PoolingType::MaxUnsigned:
@@ -762,7 +762,7 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcHwcfQOp>(
762762
/*scalarMap=*/{},
763763
/*scalarMap=*/{},
764764
/*outputMap=*/{N, H, W, F}})
765-
.matchBody(/*zeroPointOffset=*/true);
765+
.matchBody(/*containsZeroPointOffset=*/true);
766766
}
767767

768768
// #inputMap = affine_map<(N, H, W, F, h, w, c) -> (N, H + h, W + w, c)>
@@ -825,7 +825,7 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwcFhwcQOp>(
825825
/*scalarMap=*/{},
826826
/*scalarMap=*/{},
827827
/*outputMap=*/{N, H, W, F}})
828-
.matchBody(/*zeroPointOffset=*/true);
828+
.matchBody(/*containsZeroPointOffset=*/true);
829829
}
830830

831831
// #inputMap = affine_map<(N, F, H, W, c, h, w) -> (N, c, H + h, W + w)>
@@ -888,7 +888,7 @@ bool isaConvolutionOpOfType<linalg::Conv2DNchwFchwQOp>(
888888
/*scalarMap=*/{},
889889
/*scalarMap=*/{},
890890
/*outputMap=*/{N, F, H, W}})
891-
.matchBody(/*zeroPointOffset=*/true);
891+
.matchBody(/*containsZeroPointOffset=*/true);
892892
}
893893

894894
// #inputMap = affine_map<(N, G, F, H, W, c, h, w) -> (N, G, c, H + h, W + w)>
@@ -987,7 +987,7 @@ bool isaConvolutionOpOfType<linalg::Conv2DNgchwGfchwQOp>(
987987
/*scalarMap=*/{},
988988
/*scalarMap=*/{},
989989
/*outputMap=*/{N, G, F, H, W}})
990-
.matchBody(/*zeroPointOffset=*/true);
990+
.matchBody(/*containsZeroPointOffset=*/true);
991991
}
992992

993993
// #inputMap = affine_map<(N, H, W, G, F, h, w, c) -> (N, H + h, W + w, G, c)>
@@ -1054,7 +1054,7 @@ bool isaConvolutionOpOfType<linalg::Conv2DNhwgcGfhwcQOp>(
10541054
/*scalarMap=*/{},
10551055
/*scalarMap=*/{},
10561056
/*outputMap=*/{N, H, W, G, F}})
1057-
.matchBody(/*zeroPointOffset=*/true);
1057+
.matchBody(/*containsZeroPointOffset=*/true);
10581058
}
10591059

10601060
// #inputMap = affine_map<(D, H, W, d, h, w) -> (D + d, H + h, W + w)>
@@ -1088,6 +1088,114 @@ bool isaConvolutionOpOfType<linalg::Conv3DOp>(LinalgOp op,
10881088
.matchBody();
10891089
}
10901090

1091+
// #inputMap = affine_map<(N, D, H, W, F, d, h, w, c)
1092+
// -> (N, D + d, H + h, W + w, c)>
1093+
// #filterMap = affine_map<(N, D, H, W, F, d, h, w, c) -> (d, h, w, c, F)>
1094+
// #outputMap = affine_map<(N, D, H, W, F, d, h, w, c) -> (N, D, H, W, F)>
1095+
template <>
1096+
bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfOp>(
1097+
LinalgOp op, SmallVector<int64_t> *dilations,
1098+
SmallVector<int64_t> *strides) {
1099+
if (isa<linalg::Conv3DNdhwcDhwcfOp>(op))
1100+
return true;
1101+
1102+
assert(isaConvolutionOpInterface(op) &&
1103+
"expected op to implement ConvolutionOpInterface");
1104+
1105+
ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
1106+
AffineExpr N = m.dim(0);
1107+
AffineExpr D = m.dim(1);
1108+
AffineExpr H = m.dim(2);
1109+
AffineExpr W = m.dim(3);
1110+
AffineExpr F = m.dim(4);
1111+
AffineExpr d = m.dim(5);
1112+
AffineExpr h = m.dim(6);
1113+
AffineExpr w = m.dim(7);
1114+
AffineExpr c = m.dim(8);
1115+
1116+
return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
1117+
.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
1118+
.matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
1119+
.matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
1120+
m.strided(W, w, 2), c},
1121+
/*filterMap=*/{d, h, w, c, F},
1122+
/*outputMap=*/{N, D, H, W, F}})
1123+
.matchBody();
1124+
}
1125+
1126+
// #inputMap = affine_map<(N, D, H, W, F, d, h, w, c)
1127+
// -> (N, D + d, H + h, W + w, c)>
1128+
// #filterMap = affine_map<(N, D, H, W, F, d, h, w, c) -> (d, h, w, c, F)>
1129+
// #scalarMap = affine_map<(N, D, H, W, F, d, h, w, c) -> ()>
1130+
// #outputMap = affine_map<(N, D, H, W, F, d, h, w, c) -> (N, D, H, W, F)>
1131+
template <>
1132+
bool isaConvolutionOpOfType<linalg::Conv3DNdhwcDhwcfQOp>(
1133+
LinalgOp op, SmallVector<int64_t> *dilations,
1134+
SmallVector<int64_t> *strides) {
1135+
if (isa<linalg::Conv3DNdhwcDhwcfQOp>(op))
1136+
return true;
1137+
1138+
assert(isaConvolutionOpInterface(op) &&
1139+
"expected op to implement ConvolutionOpInterface");
1140+
1141+
ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
1142+
AffineExpr N = m.dim(0);
1143+
AffineExpr D = m.dim(1);
1144+
AffineExpr H = m.dim(2);
1145+
AffineExpr W = m.dim(3);
1146+
AffineExpr F = m.dim(4);
1147+
AffineExpr d = m.dim(5);
1148+
AffineExpr h = m.dim(6);
1149+
AffineExpr w = m.dim(7);
1150+
AffineExpr c = m.dim(8);
1151+
1152+
return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
1153+
.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
1154+
.matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
1155+
.matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
1156+
m.strided(W, w, 2), c},
1157+
/*filterMap=*/{d, h, w, c, F},
1158+
/*scalarMap=*/{},
1159+
/*scalarMap=*/{},
1160+
/*outputMap=*/{N, D, H, W, F}})
1161+
.matchBody(/*containsZeroPointOffset=*/true);
1162+
}
1163+
1164+
// #inputMap = affine_map<(N, F, D, H, W, c, d, h, w)
1165+
// -> (N, c, D + d, H + h, W + w)>
1166+
// #filterMap = affine_map<(N, F, D, H, W, c, d, h, w) -> (F, c, d, h, w)>
1167+
// #outputMap = affine_map<(N, F, D, H, W, c, d, h, w) -> (N, F, D, H, W)>
1168+
template <>
1169+
bool isaConvolutionOpOfType<linalg::Conv3DNcdhwFcdhwOp>(
1170+
LinalgOp op, SmallVector<int64_t> *dilations,
1171+
SmallVector<int64_t> *strides) {
1172+
if (isa<linalg::Conv3DNcdhwFcdhwOp>(op))
1173+
return true;
1174+
1175+
assert(isaConvolutionOpInterface(op) &&
1176+
"expected op to implement ConvolutionOpInterface");
1177+
1178+
ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
1179+
AffineExpr N = m.dim(0);
1180+
AffineExpr F = m.dim(1);
1181+
AffineExpr D = m.dim(2);
1182+
AffineExpr H = m.dim(3);
1183+
AffineExpr W = m.dim(4);
1184+
AffineExpr c = m.dim(5);
1185+
AffineExpr d = m.dim(6);
1186+
AffineExpr h = m.dim(7);
1187+
AffineExpr w = m.dim(8);
1188+
1189+
return m.matchStride(/*iDim=*/2, /*fDim=*/2, /*oDim=*/2, /*idx=*/0)
1190+
.matchStride(/*iDim=*/3, /*fDim=*/3, /*oDim=*/3, /*idx=*/1)
1191+
.matchStride(/*iDim=*/4, /*fDim=*/4, /*oDim=*/4, /*idx=*/2)
1192+
.matchMaps({/*inputMap=*/{N, c, m.strided(D, d, 0), m.strided(H, h, 1),
1193+
m.strided(W, w, 2)},
1194+
/*filterMap=*/{F, c, d, h, w},
1195+
/*outputMap=*/{N, F, D, H, W}})
1196+
.matchBody();
1197+
}
1198+
10911199
// #inputMap = affine_map<(N, W, C, w) -> (N, C, W + w)>
10921200
// #filterMap = affine_map<(N, W, C, w) -> (C, w)>
10931201
// #outputMap = affine_map<(N, W, C, w) -> (N, C, W)>
@@ -1254,7 +1362,7 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcQOp>(
12541362
/*scalarMap=*/{},
12551363
/*scalarMap=*/{},
12561364
/*outputMap=*/{N, H, W, C}})
1257-
.matchBody(/*zeroPointOffset=*/true);
1365+
.matchBody(/*containsZeroPointOffset=*/true);
12581366
}
12591367

12601368
// #inputMap = affine_map<(N, H, W, C, CM, h, w) -> (N, H + h, W + w, C)>
@@ -1317,7 +1425,73 @@ bool isaConvolutionOpOfType<linalg::DepthwiseConv2DNhwcHwcmQOp>(
13171425
/*scalarMap=*/{},
13181426
/*scalarMap=*/{},
13191427
/*outputMap=*/{N, H, W, C, CM}})
1320-
.matchBody(/*zeroPointOffset=*/true);
1428+
.matchBody(/*containsZeroPointOffset=*/true);
1429+
}
1430+
1431+
// #inputMap = affine_map<(N, D, H, W, d, h, w, C) -> (N, D + d, H + h, W + w, C)>
1432+
// #filterMap = affine_map<(N, D, H, W, d, h, w, C) -> (d, h, w, C)>
1433+
// #outputMap = affine_map<(N, D, H, W, d, h, w, C) -> (N, D, H, W, C)>
1434+
template <>
1435+
bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNdhwcDhwcOp>(
1436+
LinalgOp op, SmallVector<int64_t> *dilations,
1437+
SmallVector<int64_t> *strides) {
1438+
if (isa<linalg::DepthwiseConv3DNdhwcDhwcOp>(op))
1439+
return true;
1440+
1441+
assert(isaConvolutionOpInterface(op) &&
1442+
"expected op to implement ConvolutionOpInterface");
1443+
1444+
ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
1445+
AffineExpr N = m.dim(0);
1446+
AffineExpr D = m.dim(1);
1447+
AffineExpr H = m.dim(2);
1448+
AffineExpr W = m.dim(3);
1449+
AffineExpr d = m.dim(4);
1450+
AffineExpr h = m.dim(5);
1451+
AffineExpr w = m.dim(6);
1452+
AffineExpr C = m.dim(7);
1453+
1454+
return m.matchStride(/*iDim=*/1, /*fDim=*/0, /*oDim=*/1, /*idx=*/0)
1455+
.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/1)
1456+
.matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/2)
1457+
.matchMaps({/*inputMap=*/{N, m.strided(D, d, 0), m.strided(H, h, 1),
1458+
m.strided(W, w, 2), C},
1459+
/*filterMap=*/{d, h, w, C},
1460+
/*outputMap=*/{N, D, H, W, C}})
1461+
.matchBody();
1462+
}
1463+
1464+
// #inputMap = affine_map<(N, D, H, W, d, h, w, C) -> (N, C, D + d, H + h, W + w)>
1465+
// #filterMap = affine_map<(N, D, H, W, d, h, w, C) -> (C, d, h, w)>
1466+
// #outputMap = affine_map<(N, D, H, W, d, h, w, C) -> (N, C, D, H, W)>
1467+
template <>
1468+
bool isaConvolutionOpOfType<linalg::DepthwiseConv3DNcdhwCdhwOp>(
1469+
LinalgOp op, SmallVector<int64_t> *dilations,
1470+
SmallVector<int64_t> *strides) {
1471+
if (isa<linalg::DepthwiseConv3DNcdhwCdhwOp>(op))
1472+
return true;
1473+
1474+
assert(isaConvolutionOpInterface(op) &&
1475+
"expected op to implement ConvolutionOpInterface");
1476+
1477+
ConvMatcherBuilder m(op, /*spatialRank=*/3, dilations, strides);
1478+
AffineExpr N = m.dim(0);
1479+
AffineExpr D = m.dim(1);
1480+
AffineExpr H = m.dim(2);
1481+
AffineExpr W = m.dim(3);
1482+
AffineExpr d = m.dim(4);
1483+
AffineExpr h = m.dim(5);
1484+
AffineExpr w = m.dim(6);
1485+
AffineExpr C = m.dim(7);
1486+
1487+
return m.matchStride(/*iDim=*/2, /*fDim=*/1, /*oDim=*/2, /*idx=*/0)
1488+
.matchStride(/*iDim=*/3, /*fDim=*/2, /*oDim=*/3, /*idx=*/1)
1489+
.matchStride(/*iDim=*/4, /*fDim=*/3, /*oDim=*/4, /*idx=*/2)
1490+
.matchMaps({/*inputMap=*/{N, C, m.strided(D, d, 0), m.strided(H, h, 1),
1491+
m.strided(W, w, 2)},
1492+
/*filterMap=*/{C, d, h, w},
1493+
/*outputMap=*/{N, C, D, H, W}})
1494+
.matchBody();
13211495
}
13221496

13231497
// #inputMap = affine_map<(N, D, H, W, CM, d, h, w, C)

mlir/test/Dialect/Linalg/convolution/roundtrip-convolution.mlir

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,45 @@ func.func @conv_3d(%in : tensor<?x?x?xf32>, %filter : tensor<?x?x?xf32>, %out :
218218

219219
// -----
220220

221+
func.func @conv_3d_ndhwc_dhwcf(%input: tensor<?x?x?x?x?xf32>, %filter: tensor<?x?x?x?x?xf32>, %output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32> {
222+
%0 = linalg.conv_3d_ndhwc_dhwcf
223+
{dilations = dense<2> : tensor<3xi64>, strides = dense<3> : tensor<3xi64>}
224+
ins (%input, %filter: tensor<?x?x?x?x?xf32>, tensor<?x?x?x?x?xf32>)
225+
outs (%output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32>
226+
return %0 : tensor<?x?x?x?x?xf32>
227+
}
228+
// CHECK: @conv_3d_ndhwc_dhwcf
229+
// CHECK: linalg.conv_3d_ndhwc_dhwcf
230+
// CHECK-SAME: dilations = dense<2> : tensor<3xi64>, strides = dense<3> : tensor<3xi64>
231+
232+
// -----
233+
234+
func.func @conv_3d_ndhwc_dhwcf_q(%input: tensor<?x?x?x?x?xi8>, %filter: tensor<?x?x?x?x?xi8>, %output: tensor<?x?x?x?x?xi32>, %zp_input: i32, %zp_filter: i32) -> tensor<?x?x?x?x?xi32> {
235+
%0 = linalg.conv_3d_ndhwc_dhwcf_q
236+
{dilations = dense<1> : tensor<3xi64>, strides = dense<1> : tensor<3xi64>}
237+
ins (%input, %filter, %zp_input, %zp_filter : tensor<?x?x?x?x?xi8>, tensor<?x?x?x?x?xi8>, i32, i32)
238+
outs (%output: tensor<?x?x?x?x?xi32>) -> tensor<?x?x?x?x?xi32>
239+
return %0 : tensor<?x?x?x?x?xi32>
240+
}
241+
// CHECK: @conv_3d_ndhwc_dhwcf_q
242+
// CHECK: linalg.conv_3d_ndhwc_dhwcf_q
243+
// CHECK-SAME: dilations = dense<1> : tensor<3xi64>, strides = dense<1> : tensor<3xi64>
244+
245+
// -----
246+
247+
func.func @conv_3d_ncdhw_fcdhw(%input: tensor<?x?x?x?x?xf32>, %filter: tensor<?x?x?x?x?xf32>, %output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32> {
248+
%0 = linalg.conv_3d_ncdhw_fcdhw
249+
{dilations = dense<[1, 2, 3]> : tensor<3xi64>, strides = dense<[4, 5, 6]> : tensor<3xi64>}
250+
ins (%input, %filter: tensor<?x?x?x?x?xf32>, tensor<?x?x?x?x?xf32>)
251+
outs (%output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32>
252+
return %0 : tensor<?x?x?x?x?xf32>
253+
}
254+
// CHECK: @conv_3d_ncdhw_fcdhw
255+
// CHECK: linalg.conv_3d_ncdhw_fcdhw
256+
// CHECK-SAME: dilations = dense<[1, 2, 3]> : tensor<3xi64>, strides = dense<[4, 5, 6]> : tensor<3xi64>
257+
258+
// -----
259+
221260
// -------------------------------
222261
// Depthwise Convolution ops - 1D.
223262
// -------------------------------
@@ -334,6 +373,32 @@ func.func @depthwise_conv_2d_nhwc_hwcm_q(%input: tensor<?x?x?x?xi8>, %filter: te
334373
// Depthwise Convolution ops - 3D.
335374
// -------------------------------
336375

376+
func.func @depthwise_conv_3d_ndhwc_dhwc(%input: tensor<?x?x?x?x?xf32>, %filter: tensor<?x?x?x?xf32>, %output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32> {
377+
%0 = linalg.depthwise_conv_3d_ndhwc_dhwc
378+
{dilations = dense<2> : tensor<3xi64>, strides = dense<3> : tensor<3xi64>}
379+
ins (%input, %filter: tensor<?x?x?x?x?xf32>, tensor<?x?x?x?xf32>)
380+
outs (%output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32>
381+
return %0 : tensor<?x?x?x?x?xf32>
382+
}
383+
// CHECK: @depthwise_conv_3d_ndhwc_dhwc
384+
// CHECK: linalg.depthwise_conv_3d_ndhwc_dhwc
385+
// CHECK-SAME: dilations = dense<2> : tensor<3xi64>, strides = dense<3> : tensor<3xi64>
386+
387+
// -----
388+
389+
func.func @depthwise_conv_3d_ncdhw_cdhw(%input: tensor<?x?x?x?x?xf32>, %filter: tensor<?x?x?x?xf32>, %output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32> {
390+
%0 = linalg.depthwise_conv_3d_ncdhw_cdhw
391+
{dilations = dense<[1, 2, 3]> : tensor<3xi64>, strides = dense<[4, 5, 6]> : tensor<3xi64>}
392+
ins (%input, %filter: tensor<?x?x?x?x?xf32>, tensor<?x?x?x?xf32>)
393+
outs (%output: tensor<?x?x?x?x?xf32>) -> tensor<?x?x?x?x?xf32>
394+
return %0 : tensor<?x?x?x?x?xf32>
395+
}
396+
// CHECK: @depthwise_conv_3d_ncdhw_cdhw
397+
// CHECK: linalg.depthwise_conv_3d_ncdhw_cdhw
398+
// CHECK-SAME: dilations = dense<[1, 2, 3]> : tensor<3xi64>, strides = dense<[4, 5, 6]> : tensor<3xi64>
399+
400+
// -----
401+
337402
func.func @depthwise_conv_3d_ndhwc_dhwcm(%input: tensor<?x?x?x?x?xf32>, %filter: tensor<?x?x?x?x?xf32>, %output: tensor<?x?x?x?x?x?xf32>) -> tensor<?x?x?x?x?x?xf32> {
338403
%0 = linalg.depthwise_conv_3d_ndhwc_dhwcm
339404
{dilations = dense<1> : tensor<3xi64>, strides = dense<1> : tensor<3xi64>}

0 commit comments

Comments
 (0)