brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 5c321d4 Raw
196 lines · plain
1// RUN: mlir-opt -split-input-file -transform-interpreter -cse %s | FileCheck %s2 3///----------------------------------------------------------------------------------------4/// ATM, all tests in this file require masking. As the support for masking is5/// limited to depthwise convs, only that variant of convolutions is tested6/// ATM.7///8/// TODO1: Add more types of convolutions (transform.structured.vectorize9/// usually doesn't require masking when vector sizes are not specified)10/// TODO2: Add support for masking non-depthwise convs.11///----------------------------------------------------------------------------------------12 13func.func @depthwise_conv1d_nwc_wc_1x8x3xi8_tensor(%input: tensor<1x8x?xi8>,14                                                   %filter: tensor<1x?xi8>,15                                                   %output: tensor<1x8x?xi8>) -> (tensor<1x8x?xi8>) {16  %res = linalg.depthwise_conv_1d_nwc_wc17    {dilations = dense<1> : vector<1xi64>,18    strides = dense<1> : vector<1xi64>}19    ins(%input, %filter : tensor<1x8x?xi8>, tensor<1x?xi8>)20    outs(%output : tensor<1x8x?xi8>) -> tensor<1x8x?xi8>21  return %res : tensor<1x8x?xi8>22}23 24module attributes {transform.with_named_sequence} {25  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {26    %0 = transform.structured.match ops{["linalg.depthwise_conv_1d_nwc_wc"]} in %arg0 : (!transform.any_op) -> !transform.any_op27    transform.structured.vectorize %0 vector_sizes [1, 8, 4, 1] : !transform.any_op28    transform.yield29  }30}31 32// CHECK-LABEL:   func.func @depthwise_conv1d_nwc_wc_1x8x3xi8_tensor(33// CHECK-SAME:      %[[INPUT:.*]]: tensor<1x8x?xi8>,34// CHECK-SAME:      %[[FILTER:.*]]: tensor<1x?xi8>,35// CHECK-SAME:      %[[OUTPUT:.*]]: tensor<1x8x?xi8>) -> tensor<1x8x?xi8> {36 37// CHECK:           %[[C1:.*]] = arith.constant 1 : index38// CHECK:           %[[C0:.*]] = arith.constant 0 : index39// CHECK:           %[[PAD:.*]] = arith.constant 0 : i840 41/// Create a mask for the input tensor42// CHECK:           %[[C2:.*]] = arith.constant 2 : index43// CHECK:           %[[CH_DIM_IN:.*]] = tensor.dim %[[INPUT]], %[[C2]] : tensor<1x8x?xi8>44// CHECK:           %[[C8:.*]] = arith.constant 8 : index45// CHECK:           %[[MASK_IN:.*]] = vector.create_mask %[[C1]], %[[C8]], %[[CH_DIM_IN]] : vector<1x8x4xi1>46/// Read the input tensor47// CHECK:           %[[VEC_IN:.*]] = vector.mask %[[MASK_IN]] { vector.transfer_read %[[INPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : tensor<1x8x?xi8>, vector<1x8x4xi8> } : vector<1x8x4xi1> -> vector<1x8x4xi8>48 49/// Create a mask for the filter tensor50// CHECK:           %[[CH_DIM_FLT:.*]] = tensor.dim %[[FILTER]], %[[C1]] : tensor<1x?xi8>51// CHECK:           %[[MASK_FLT:.*]] = vector.create_mask %[[C1]], %[[CH_DIM_FLT]] : vector<1x4xi1>52/// Read the filter tensor53// CHECK:           %[[VEC_FLT:.*]] = vector.mask %[[MASK_FLT]] { vector.transfer_read %[[FILTER]]{{\[}}%[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true]} : tensor<1x?xi8>, vector<1x4xi8> } : vector<1x4xi1> -> vector<1x4xi8>54 55/// Create a mask for the output tensor56// CHECK:           %[[CH_DIM_OUT:.*]] = tensor.dim %[[OUTPUT]], %[[C2]] : tensor<1x8x?xi8>57// CHECK:           %[[MASK_OUT:.*]] = vector.create_mask %[[C1]], %[[C8]], %[[CH_DIM_OUT]] : vector<1x8x4xi1>58// CHECK:           %[[VEC_OUT:.*]] = vector.mask %[[MASK_OUT]] { vector.transfer_read %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : tensor<1x8x?xi8>, vector<1x8x4xi8> } : vector<1x8x4xi1> -> vector<1x8x4xi8>59 60/// Convolution61// CHECK:           %[[IN_1:.*]] = vector.extract_strided_slice %[[VEC_IN]] {offsets = [0, 0, 0], sizes = [1, 8, 4], strides = [1, 1, 1]} : vector<1x8x4xi8> to vector<1x8x4xi8>62// CHECK:           %[[FLT_1:.*]] = vector.extract %[[VEC_FLT]][0] : vector<4xi8> from vector<1x4xi8>63// CHECK:           %[[OUT_1:.*]] = vector.extract_strided_slice %[[VEC_OUT]] {offsets = [0, 0, 0], sizes = [1, 8, 4], strides = [1, 1, 1]} : vector<1x8x4xi8> to vector<1x8x4xi8>64// CHECK:           %[[FLT_1_B:.*]] = vector.broadcast %[[FLT_1]] : vector<4xi8> to vector<1x8x4xi8>65// CHECK:           %[[MULI:.*]] = arith.muli %[[IN_1]], %[[FLT_1_B]] : vector<1x8x4xi8>66// CHECK:           %[[ADDI:.*]] = arith.addi %[[MULI]], %[[OUT_1]] : vector<1x8x4xi8>67// CHECK:           %[[OUT_INS:.*]] = vector.insert_strided_slice %[[ADDI]], %[[VEC_OUT]] {offsets = [0, 0, 0], strides = [1, 1, 1]} : vector<1x8x4xi8> into vector<1x8x4xi8>68// CHECK:           %[[OUT:.*]] = vector.mask %[[MASK_OUT]] { vector.transfer_write %[[OUT_INS]], %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]] {in_bounds = [true, true, true]} : vector<1x8x4xi8>, tensor<1x8x?xi8> } : vector<1x8x4xi1> -> tensor<1x8x?xi8>69// CHECK:           return %[[OUT]] : tensor<1x8x?xi8>70 71// -----72 73func.func @depthwise_conv1d_nwc_wc_1x8x3xi8_tensor_scalable(74      %input: tensor<1x8x?xi8>,75      %filter: tensor<1x?xi8>,76      %output: tensor<1x8x?xi8>) -> (tensor<1x8x?xi8>) {77  %res = linalg.depthwise_conv_1d_nwc_wc78    {dilations = dense<1> : vector<1xi64>,79    strides = dense<1> : vector<1xi64>}80    ins(%input, %filter : tensor<1x8x?xi8>, tensor<1x?xi8>)81    outs(%output : tensor<1x8x?xi8>) -> tensor<1x8x?xi8>82  return %res : tensor<1x8x?xi8>83}84 85module attributes {transform.with_named_sequence} {86  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {87    %0 = transform.structured.match ops{["linalg.depthwise_conv_1d_nwc_wc"]} in %arg0 : (!transform.any_op) -> !transform.any_op88    transform.structured.vectorize %0 vector_sizes [1, 8, [4], 1] : !transform.any_op89    transform.yield90  }91}92 93// CHECK-LABEL:   func.func @depthwise_conv1d_nwc_wc_1x8x3xi8_tensor_scalable(94// CHECK-SAME:      %[[INPUT:.*]]: tensor<1x8x?xi8>,95// CHECK-SAME:      %[[FILTER:.*]]: tensor<1x?xi8>,96// CHECK-SAME:      %[[OUTPUT:.*]]: tensor<1x8x?xi8>) -> tensor<1x8x?xi8> {97 98// CHECK:           %[[C1:.*]] = arith.constant 1 : index99// CHECK:           %[[C0:.*]] = arith.constant 0 : index100// CHECK:           %[[PAD:.*]] = arith.constant 0 : i8101 102/// Create a mask for the input tensor103// CHECK:           %[[C2:.*]] = arith.constant 2 : index104// CHECK:           %[[CH_DIM_IN:.*]] = tensor.dim %[[INPUT]], %[[C2]] : tensor<1x8x?xi8>105// CHECK:           %[[C8:.*]] = arith.constant 8 : index106// CHECK:           %[[MASK_IN:.*]] = vector.create_mask %[[C1]], %[[C8]], %[[CH_DIM_IN]] : vector<1x8x[4]xi1>107/// Read the input tensor108// CHECK:           %[[VEC_IN:.*]] = vector.mask %[[MASK_IN]] { vector.transfer_read %[[INPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : tensor<1x8x?xi8>, vector<1x8x[4]xi8> } : vector<1x8x[4]xi1> -> vector<1x8x[4]xi8>109 110/// Create a mask for the filter tensor111// CHECK:           %[[CH_DIM_FLT:.*]] = tensor.dim %[[FILTER]], %[[C1]] : tensor<1x?xi8>112// CHECK:           %[[MASK_FLT:.*]] = vector.create_mask %[[C1]], %[[CH_DIM_FLT]] : vector<1x[4]xi1>113/// Read the filter tensor114// CHECK:           %[[VEC_FLT:.*]] = vector.mask %[[MASK_FLT]] { vector.transfer_read %[[FILTER]]{{\[}}%[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true]} : tensor<1x?xi8>, vector<1x[4]xi8> } : vector<1x[4]xi1> -> vector<1x[4]xi8>115 116/// Create a mask for the output tensor117// CHECK:           %[[CH_DIM_OUT:.*]] = tensor.dim %[[OUTPUT]], %[[C2]] : tensor<1x8x?xi8>118// CHECK:           %[[MASK_OUT:.*]] = vector.create_mask %[[C1]], %[[C8]], %[[CH_DIM_OUT]] : vector<1x8x[4]xi1>119/// Read the output tensor120// CHECK:           %[[VEC_OUT:.*]] = vector.mask %[[MASK_OUT]] { vector.transfer_read %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : tensor<1x8x?xi8>, vector<1x8x[4]xi8> } : vector<1x8x[4]xi1> -> vector<1x8x[4]xi8>121 122/// Convolution123// CHECK:           %[[IN_1:.*]] = vector.extract_strided_slice %[[VEC_IN]] {offsets = [0, 0, 0], sizes = [1, 8, 4], strides = [1, 1, 1]} : vector<1x8x[4]xi8> to vector<1x8x[4]xi8>124// CHECK:           %[[FLT_1:.*]] = vector.extract %[[VEC_FLT]][0] : vector<[4]xi8> from vector<1x[4]xi8>125// CHECK:           %[[OUT_1:.*]] = vector.extract_strided_slice %[[VEC_OUT]] {offsets = [0, 0, 0], sizes = [1, 8, 4], strides = [1, 1, 1]} : vector<1x8x[4]xi8> to vector<1x8x[4]xi8>126// CHECK:           %[[FLT_1_B:.*]] = vector.broadcast %[[FLT_1]] : vector<[4]xi8> to vector<1x8x[4]xi8>127// CHECK:           %[[MULI:.*]] = arith.muli %[[IN_1]], %[[FLT_1_B]] : vector<1x8x[4]xi8>128// CHECK:           %[[ADDI:.*]] = arith.addi %[[MULI]], %[[OUT_1]] : vector<1x8x[4]xi8>129// CHECK:           %[[OUT_INS:.*]] = vector.insert_strided_slice %[[ADDI]], %[[VEC_OUT]] {offsets = [0, 0, 0], strides = [1, 1, 1]} : vector<1x8x[4]xi8> into vector<1x8x[4]xi8>130// CHECK:           %[[OUT:.*]] = vector.mask %[[MASK_OUT]] { vector.transfer_write %[[OUT_INS]], %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]] {in_bounds = [true, true, true]} : vector<1x8x[4]xi8>, tensor<1x8x?xi8> } : vector<1x8x[4]xi1> -> tensor<1x8x?xi8>131// CHECK:           return %[[OUT]] : tensor<1x8x?xi8>132 133// -----134 135func.func @depthwise_conv1d_nwc_wc_3x5x4xf32_memref_dilation_2(136      %input: memref<3x5x?xf32>,137      %filter: memref<2x?xf32>,138      %output: memref<3x2x?xf32>) {139  linalg.depthwise_conv_1d_nwc_wc140    {dilations = dense<2> : tensor<1xi64>, strides = dense<1> : tensor<1xi64>}141    ins(%input, %filter : memref<3x5x?xf32>, memref<2x?xf32>)142    outs(%output : memref<3x2x?xf32>)143  return144}145 146module attributes {transform.with_named_sequence} {147  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {148    %0 = transform.structured.match ops{["linalg.depthwise_conv_1d_nwc_wc"]} in %arg0 : (!transform.any_op) -> !transform.any_op149    transform.structured.vectorize %0 vector_sizes [3, 2, [4], 2] : !transform.any_op150    transform.yield151  }152}153 154// CHECK-LABEL:   func.func @depthwise_conv1d_nwc_wc_3x5x4xf32_memref_dilation_2(155// CHECK-SAME:      %[[INPUT:.*]]: memref<3x5x?xf32>,156// CHECK-SAME:      %[[FILTER:.*]]: memref<2x?xf32>,157// CHECK-SAME:      %[[OUTPUT:.*]]: memref<3x2x?xf32>) {158 159// CHECK:           %[[C1:.*]] = arith.constant 1 : index160// CHECK:           %[[C0:.*]] = arith.constant 0 : index161// CHECK:           %[[PAD:.*]] = arith.constant 0.000000e+00 : f32162// CHECK:           %[[C2:.*]] = arith.constant 2 : index163 164/// Create a mask for the input tensor165// CHECK:           %[[CH_DIM_IN:.*]] = memref.dim %[[INPUT]], %[[C2]] : memref<3x5x?xf32>166// CHECK:           %[[C3:.*]] = arith.constant 3 : index167// CHECK:           %[[C5:.*]] = arith.constant 5 : index168// CHECK:           %[[MASK_IN:.*]] = vector.create_mask %[[C3]], %[[C5]], %[[CH_DIM_IN]] : vector<3x4x[4]xi1>169/// Read the input tensor170// CHECK:           %[[VEC_IN:.*]] = vector.mask %[[MASK_IN]] { vector.transfer_read %[[INPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : memref<3x5x?xf32>, vector<3x4x[4]xf32> } : vector<3x4x[4]xi1> -> vector<3x4x[4]xf32>171 172/// Create a mask for the filter tensor173// CHECK:           %[[CH_DIM_FLT:.*]] = memref.dim %[[FILTER]], %[[C1]] : memref<2x?xf32>174// CHECK:           %[[MASK_FLT:.*]] = vector.create_mask %[[C2]], %[[CH_DIM_FLT]] : vector<2x[4]xi1>175/// Read the filter tensor176// CHECK:           %[[VEC_FLT:.*]] = vector.mask %[[MASK_FLT]] { vector.transfer_read %[[FILTER]]{{\[}}%[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true]} : memref<2x?xf32>, vector<2x[4]xf32> } : vector<2x[4]xi1> -> vector<2x[4]xf32>177 178/// Create a mask for the output tensor179// CHECK:           %[[CH_DIM_OUT:.*]] = memref.dim %[[OUTPUT]], %[[C2]] : memref<3x2x?xf32>180// CHECK:           %[[MASK_OUT:.*]] = vector.create_mask %[[C3]], %[[C2]], %[[CH_DIM_OUT]] : vector<3x2x[4]xi1>181/// Read the output tensor182// CHECK:           %[[VEC_OUT:.*]] = vector.mask %[[MASK_OUT]] { vector.transfer_read %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]], %[[PAD]] {in_bounds = [true, true, true]} : memref<3x2x?xf32>, vector<3x2x[4]xf32> } : vector<3x2x[4]xi1> -> vector<3x2x[4]xf32>183 184/// Convolution185// CHECK:           %[[IN_1:.*]] = vector.extract_strided_slice %[[VEC_IN]] {offsets = [0, 0, 0], sizes = [3, 2, 4], strides = [1, 1, 1]} : vector<3x4x[4]xf32> to vector<3x2x[4]xf32>186// CHECK:           %[[IN_2:.*]] = vector.extract_strided_slice %[[VEC_IN]] {offsets = [0, 2, 0], sizes = [3, 2, 4], strides = [1, 1, 1]} : vector<3x4x[4]xf32> to vector<3x2x[4]xf32>187// CHECK:           %[[FLT_1:.*]] = vector.extract %[[VEC_FLT]][0] : vector<[4]xf32> from vector<2x[4]xf32>188// CHECK:           %[[FLT_2:.*]] = vector.extract %[[VEC_FLT]][1] : vector<[4]xf32> from vector<2x[4]xf32>189// CHECK:           %[[OUT_1:.*]] = vector.extract_strided_slice %[[VEC_OUT]] {offsets = [0, 0, 0], sizes = [3, 2, 4], strides = [1, 1, 1]} : vector<3x2x[4]xf32> to vector<3x2x[4]xf32>190// CHECK:           %[[FLT_1_B:.*]] = vector.broadcast %[[FLT_1]] : vector<[4]xf32> to vector<3x2x[4]xf32>191// CHECK:           %[[FMA_1:.*]] = vector.fma %[[IN_1]], %[[FLT_1_B]], %[[OUT_1]] : vector<3x2x[4]xf32>192// CHECK:           %[[FLT_2_B:.*]] = vector.broadcast %[[FLT_2]] : vector<[4]xf32> to vector<3x2x[4]xf32>193// CHECK:           %[[FMA_2:.*]] = vector.fma %[[IN_2]], %[[FLT_2_B]], %[[FMA_1]] : vector<3x2x[4]xf32>194// CHECK:           %[[OUT_INS:.*]] = vector.insert_strided_slice %[[FMA_2]], %[[VEC_OUT]] {offsets = [0, 0, 0], strides = [1, 1, 1]} : vector<3x2x[4]xf32> into vector<3x2x[4]xf32>195// CHECK:           vector.mask %[[MASK_OUT]] { vector.transfer_write %[[OUT_INS]], %[[OUTPUT]]{{\[}}%[[C0]], %[[C0]], %[[C0]]] {in_bounds = [true, true, true]} : vector<3x2x[4]xf32>, memref<3x2x?xf32> } : vector<3x2x[4]xi1>196