// RUN: mlir-opt -test-linalg-codegen-strategy="decompose" -split-input-file %s | FileCheck %s // CHECK-LABEL: func @conv2d_nhwc_4x1x2x8_tensor // CHECK-SAME: (%[[INPUT:.+]]: tensor<4x1x6x3xf32>, %[[FILTER:.+]]: tensor<1x2x3x8xf32>, %[[INIT:.+]]: tensor<4x1x2x8xf32>) func @conv2d_nhwc_4x1x2x8_tensor(%input: tensor<4x1x6x3xf32>, %filter: tensor<1x2x3x8xf32>, %init: tensor<4x1x2x8xf32>) -> tensor<4x1x2x8xf32> { %0 = linalg.conv_2d_nhwc_hwcf {dilations = dense<[2, 3]> : tensor<2xi64>, strides = dense<[3, 2]> : tensor<2xi64>} ins(%input, %filter : tensor<4x1x6x3xf32>, tensor<1x2x3x8xf32>) outs(%init : tensor<4x1x2x8xf32>) -> tensor<4x1x2x8xf32> return %0 : tensor<4x1x2x8xf32> } // CHECK: %[[INPUT_1D:.+]] = tensor.extract_slice %[[INPUT]] // CHECK-SAME{LITERAL}: [0, 0, 0, 0] [4, 1, 6, 3] [1, 1, 1, 1] : tensor<4x1x6x3xf32> to tensor<4x6x3xf32> // CHECK: %[[FILTER_1D:.+]] = tensor.extract_slice %[[FILTER]] // CHECK-SAME{LITERAL}: [0, 0, 0, 0] [1, 2, 3, 8] [1, 1, 1, 1] : tensor<1x2x3x8xf32> to tensor<2x3x8xf32> // CHECK: %[[INIT_1D:.+]] = tensor.extract_slice %[[INIT]] // CHECK-SAME{LITERAL}: [0, 0, 0, 0] [4, 1, 2, 8] [1, 1, 1, 1] : tensor<4x1x2x8xf32> to tensor<4x2x8xf32> // CHECK: %[[CONV_1D:.+]] = linalg.conv_1d_nwc_wcf // CHECK-SAME: dilations = dense<3> : vector<1xi64> // CHECK-SAME: strides = dense<2> : vector<1xi64> // CHECK-SAME: ins(%[[INPUT_1D]], %[[FILTER_1D]] : tensor<4x6x3xf32>, tensor<2x3x8xf32>) // CHECK-SAME: outs(%[[INIT_1D]] : tensor<4x2x8xf32>) // CHECK: %[[CONV_2D:.+]] = tensor.insert_slice %[[CONV_1D]] into %[[INIT]] // CHECK-SAME{LITERAL}: [0, 0, 0, 0] [4, 1, 2, 8] [1, 1, 1, 1] : tensor<4x2x8xf32> into tensor<4x1x2x8xf32> // CHECK: return %[[CONV_2D]] // ----- // CHECK-LABEL: func @conv2d_nhwc_qxqx1xq_tensor // CHECK-SAME: (%[[INPUT:.+]]: tensor, %[[FILTER:.+]]: tensor, %[[INIT:.+]]: tensor) func @conv2d_nhwc_qxqx1xq_tensor(%input: tensor, %filter: tensor, %init: tensor) -> tensor { %0 = linalg.conv_2d_nhwc_hwcf {dilations = dense<[2, 3]> : tensor<2xi64>, strides = dense<[3, 2]> : tensor<2xi64>} ins(%input, %filter : tensor, tensor) outs(%init : tensor) -> tensor return %0 : tensor } // CHECK: %[[INPUT_1D:.+]] = tensor.extract_slice %[[INPUT]] // CHECK-SAME: [0, 0, 0, 0] [%{{.*}}, %{{.*}}, 1, %{{.*}}] [1, 1, 1, 1] : // CHECK-SAME: tensor to tensor // CHECK: %[[FILTER_1D:.+]] = tensor.extract_slice %[[FILTER]] // CHECK-SAME: [0, 0, 0, 0] [%{{.*}}, 1, %{{.*}}, %{{.*}}] [1, 1, 1, 1] : // CHECK-SAME: tensor to tensor // CHECK: %[[INIT_1D:.+]] = tensor.extract_slice %[[INIT]] // CHECK-SAME: [0, 0, 0, 0] [%{{.*}}, %{{.*}}, 1, %{{.*}}] [1, 1, 1, 1] : // CHECK-SAME: tensor to tensor // CHECK: %[[CONV_1D:.+]] = linalg.conv_1d_nwc_wcf // CHECK-SAME: dilations = dense<2> : vector<1xi64> // CHECK-SAME: strides = dense<3> : vector<1xi64> // CHECK-SAME: ins(%[[INPUT_1D]], %[[FILTER_1D]] : tensor, tensor) // CHECK-SAME: outs(%[[INIT_1D]] : tensor) // CHECK: %[[CONV_2D:.+]] = tensor.insert_slice %[[CONV_1D]] into %[[INIT]] // CHECK-SAME: [0, 0, 0, 0] [%{{.*}}, %{{.*}}, 1, %{{.*}}] [1, 1, 1, 1] : // CHECK-SAME: tensor into tensor // CHECK: return %[[CONV_2D]] // ----- // Do not convert convolution ops whose window dimensions are not ones. // CHECK-LABEL: func @conv2d_nhwc_4x1x2x8_tensor func @conv2d_nhwc_4x1x2x8_tensor(%input: tensor<4x3x5x3xf32>, %filter: tensor<2x2x3x8xf32>, %init: tensor<4x1x2x8xf32>) -> tensor<4x1x2x8xf32> { // CHECK: linalg.conv_2d_nhwc_hwcf %0 = linalg.conv_2d_nhwc_hwcf {dilations = dense<[2, 3]> : tensor<2xi64>, strides = dense<1> : tensor<2xi64>} ins(%input, %filter : tensor<4x3x5x3xf32>, tensor<2x2x3x8xf32>) outs(%init : tensor<4x1x2x8xf32>) -> tensor<4x1x2x8xf32> return %0 : tensor<4x1x2x8xf32> } // ----- // CHECK-LABEL: func @depthwise_conv_2d_nhwc_hwc_tensor func @depthwise_conv_2d_nhwc_hwc_tensor(%input: tensor<1x1x113x96xf32>, %filter: tensor<1x3x96xf32>, %out: tensor<1x1x56x96xf32>) -> tensor<1x1x56x96xf32> { // CHECK: linalg.depthwise_conv_1d_nwc_wc %0 = linalg.depthwise_conv_2d_nhwc_hwc {dilations = dense<1> : vector<2xi64>, strides = dense<2> : vector<2xi64>} ins(%input, %filter: tensor<1x1x113x96xf32>, tensor<1x3x96xf32>) outs(%out: tensor<1x1x56x96xf32>) -> tensor<1x1x56x96xf32> return %0: tensor<1x1x56x96xf32> } // ----- // Do not convert convolution ops whose window dimensions are not ones. // CHECK-LABEL: func @depthwise_conv_2d_nhwc_hwc_tensor func @depthwise_conv_2d_nhwc_hwc_tensor(%input: tensor<1x113x113x96xf32>, %filter: tensor<3x3x96xf32>, %out: tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> { // CHECK: linalg.depthwise_conv_2d_nhwc_hwc %0 = linalg.depthwise_conv_2d_nhwc_hwc {dilations = dense<1> : vector<2xi64>, strides = dense<2> : vector<2xi64>} ins(%input, %filter: tensor<1x113x113x96xf32>, tensor<3x3x96xf32>) outs(%out: tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> return %0: tensor<1x56x56x96xf32> }