Skip to content

[mlir][linalg] Add a test for inferConvolutionDimsImpl #90057

New issue

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

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

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions mlir/test/Dialect/Linalg/match-ops-interpreter.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,28 @@ module attributes { transform.target_tag = "start_here" } {
return %result : tensor<10x18x15xf64>
}

func.func @convolution_depthwise(%input: tensor<1x10x196x48xf32>, %filter: tensor<1x4x48xf32>) -> tensor<1x10x191x48xf32> {
%cst = arith.constant 0.0 : f32
%empty = tensor.empty() : tensor<1x10x191x48xf32>
%fill = linalg.fill ins(%cst : f32) outs(%empty : tensor<1x10x191x48xf32>) -> tensor<1x10x191x48xf32>
// expected-remark @below {{convolution}}
// expected-remark @below {{batch dims 0}}
// expected-remark @below {{output image dims 1 : i64, 2 : i64}}
// expected-remark @below {{output channel dims}}
// expected-remark @below {{filter loop dims 4 : i64, 5 : i64}}
// expected-remark @below {{input channel dims}}
// expected-remark @below {{depth dims 3}}
Copy link
Contributor

@qedawkins qedawkins Apr 25, 2024

Choose a reason for hiding this comment

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

This doesn't look like what I would expect because it is classifying dim 3 twice. The naming might need to be improved for depthwise convolutions, but the idea with these classifications is that they tell users exactly how each different dimension appears in the indexing maps (and thus input/filter/output tensors). Right now the impl uses this to imply that all dims classified as outputChannel are only featured in the filter and output maps. Dims classified as depth appear in all three of the input, filter, and output.

I'm noticing that there is no description for depth in this comment though:

/// Find at least 1 parallel (output_image) and reduction (filter_loop)
/// dimension candidates that form a convolution subcomputation within
/// `linalgOp`. The LHS is assumed to be the convolution input while the
/// RHS is assumed as the filter.
/// These dimensions are such that:
/// 1. Optional batch dimensions that appear in the input and filter.
/// 2. The output_image dimension is involved in a cross-correlation along LHS
/// (i.e. it is a permutation on RES and LHS and has an associated
/// filter_loop in RHS).
/// 3. Optional output_channel dimension is involved in an outer-product along
/// RHS (i.e. it is a permutation on RES and RHS and does not appear in
/// LHS).
/// 4. Optional input_channel dimension appears as a permutation on LHS and
/// RHS.
/// 5. The filter_loop dimension appears as a permutation on the RHS and
/// represents the shape of the kernel cross-correlated along a
/// corresponding output_image dim.
/// 6. The input_channel dimension appears as a permutation on LHS and RHS.
/// 7. All dimensions appear only once in any given indexing map.
/// This allows e.g. detecting that some convolution is embedded within
/// `linalgOp` with some orthogonal heuristic.
/// When multiple dimension occurrences exist that match any classification
/// indices are returned in sorted order.
/// Returns a failure if `output_image` (and implicitly `filter_loop`) is empty.

(also the comment is kind of convoluted and could probably be rewritten, maybe with an example).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing this out - now I see what's happening here. IIUC, "channel" is only used for non-depthwise convolutions. For depthwise convs (HWC), this logic uses the term "depth" instead. Now, "depth" is:

  • a parallel dim
  • identical for all inputs.

It looks like this PR is breaking rather than fixing things 😂 Let me update and rephrase.

// expected-remark @below {{strides 1 : i64, 1 : i64}}
// expected-remark @below {{dilations 1 : i64, 1 : i64}}
%result = linalg.depthwise_conv_2d_nhwc_hwc {
dilations = dense<1> : tensor<2xi64>,
strides = dense<1> : tensor<2xi64>}
ins(%input, %filter : tensor<1x10x196x48xf32>, tensor<1x4x48xf32>)
outs(%fill : tensor<1x10x191x48xf32>) -> tensor<1x10x191x48xf32>

return %result : tensor<1x10x191x48xf32>
}

func.func @convolution_multi_channel(%input: tensor<2x34x68x16xf32>, %filter: tensor<8x2x3x5x16x16xf32>) -> tensor<8x32x32x16xf32> {
%cst = arith.constant 0.0 : f32
%empty = tensor.empty() : tensor<8x32x32x16xf32>
Expand Down